aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/hvc
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/tty/hvc
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/tty/hvc')
-rw-r--r--drivers/tty/hvc/Kconfig25
-rw-r--r--drivers/tty/hvc/Makefile2
-rw-r--r--drivers/tty/hvc/hvc_beat.c2
-rw-r--r--drivers/tty/hvc/hvc_console.c168
-rw-r--r--drivers/tty/hvc/hvc_console.h4
-rw-r--r--drivers/tty/hvc/hvc_irq.c2
-rw-r--r--drivers/tty/hvc/hvc_opal.c425
-rw-r--r--drivers/tty/hvc/hvc_rtas.c2
-rw-r--r--drivers/tty/hvc/hvc_udbg.c10
-rw-r--r--drivers/tty/hvc/hvc_vio.c143
-rw-r--r--drivers/tty/hvc/hvc_xen.c470
-rw-r--r--drivers/tty/hvc/hvcs.c209
-rw-r--r--drivers/tty/hvc/hvsi.c143
-rw-r--r--drivers/tty/hvc/hvsi_lib.c8
14 files changed, 384 insertions, 1229 deletions
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig
index f47b734c6a7..e371753ba92 100644
--- a/drivers/tty/hvc/Kconfig
+++ b/drivers/tty/hvc/Kconfig
@@ -24,14 +24,15 @@ config HVC_OLD_HVSI
24 depends on HVC_CONSOLE 24 depends on HVC_CONSOLE
25 default n 25 default n
26 26
27config HVC_OPAL 27config HVC_ISERIES
28 bool "OPAL Console support" 28 bool "iSeries Hypervisor Virtual Console support"
29 depends on PPC_POWERNV 29 depends on PPC_ISERIES
30 default y
30 select HVC_DRIVER 31 select HVC_DRIVER
31 select HVC_IRQ 32 select HVC_IRQ
32 default y 33 select VIOPATH
33 help 34 help
34 PowerNV machines running under OPAL need that driver to get a console 35 iSeries machines support a hypervisor virtual console.
35 36
36config HVC_RTAS 37config HVC_RTAS
37 bool "IBM RTAS Console support" 38 bool "IBM RTAS Console support"
@@ -66,23 +67,11 @@ config HVC_XEN
66 help 67 help
67 Xen virtual console device driver 68 Xen virtual console device driver
68 69
69config HVC_XEN_FRONTEND
70 bool "Xen Hypervisor Multiple Consoles support"
71 depends on HVC_XEN
72 select XEN_XENBUS_FRONTEND
73 default y
74 help
75 Xen driver for secondary virtual consoles
76
77config HVC_UDBG 70config HVC_UDBG
78 bool "udbg based fake hypervisor console" 71 bool "udbg based fake hypervisor console"
79 depends on PPC 72 depends on PPC && EXPERIMENTAL
80 select HVC_DRIVER 73 select HVC_DRIVER
81 default n 74 default n
82 help
83 This is meant to be used during HW bring up or debugging when
84 no other console mechanism exist but udbg, to get you a quick
85 console for userspace. Do NOT enable in production kernels.
86 75
87config HVC_DCC 76config HVC_DCC
88 bool "ARM JTAG DCC console" 77 bool "ARM JTAG DCC console"
diff --git a/drivers/tty/hvc/Makefile b/drivers/tty/hvc/Makefile
index 4ca3723b0a3..e2920531637 100644
--- a/drivers/tty/hvc/Makefile
+++ b/drivers/tty/hvc/Makefile
@@ -1,6 +1,6 @@
1obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi_lib.o 1obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi_lib.o
2obj-$(CONFIG_HVC_OPAL) += hvc_opal.o hvsi_lib.o
3obj-$(CONFIG_HVC_OLD_HVSI) += hvsi.o 2obj-$(CONFIG_HVC_OLD_HVSI) += hvsi.o
3obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o
4obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o 4obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o
5obj-$(CONFIG_HVC_TILE) += hvc_tile.o 5obj-$(CONFIG_HVC_TILE) += hvc_tile.o
6obj-$(CONFIG_HVC_DCC) += hvc_dcc.o 6obj-$(CONFIG_HVC_DCC) += hvc_dcc.o
diff --git a/drivers/tty/hvc/hvc_beat.c b/drivers/tty/hvc/hvc_beat.c
index 1560d235449..5fe4631e2a6 100644
--- a/drivers/tty/hvc/hvc_beat.c
+++ b/drivers/tty/hvc/hvc_beat.c
@@ -113,7 +113,7 @@ static int __init hvc_beat_init(void)
113 if (!firmware_has_feature(FW_FEATURE_BEAT)) 113 if (!firmware_has_feature(FW_FEATURE_BEAT))
114 return -ENODEV; 114 return -ENODEV;
115 115
116 hp = hvc_alloc(0, 0, &hvc_beat_get_put_ops, 16); 116 hp = hvc_alloc(0, NO_IRQ, &hvc_beat_get_put_ops, 16);
117 if (IS_ERR(hp)) 117 if (IS_ERR(hp))
118 return PTR_ERR(hp); 118 return PTR_ERR(hp);
119 hvc_beat_dev = hp; 119 hvc_beat_dev = hp;
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 13ee53bd0bf..e1aaf4f309b 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -107,7 +107,7 @@ static struct hvc_struct *hvc_get_by_index(int index)
107 list_for_each_entry(hp, &hvc_structs, next) { 107 list_for_each_entry(hp, &hvc_structs, next) {
108 spin_lock_irqsave(&hp->lock, flags); 108 spin_lock_irqsave(&hp->lock, flags);
109 if (hp->index == index) { 109 if (hp->index == index) {
110 tty_port_get(&hp->port); 110 kref_get(&hp->kref);
111 spin_unlock_irqrestore(&hp->lock, flags); 111 spin_unlock_irqrestore(&hp->lock, flags);
112 spin_unlock(&hvc_structs_lock); 112 spin_unlock(&hvc_structs_lock);
113 return hp; 113 return hp;
@@ -229,9 +229,9 @@ static int __init hvc_console_init(void)
229console_initcall(hvc_console_init); 229console_initcall(hvc_console_init);
230 230
231/* callback when the kboject ref count reaches zero. */ 231/* callback when the kboject ref count reaches zero. */
232static void hvc_port_destruct(struct tty_port *port) 232static void destroy_hvc_struct(struct kref *kref)
233{ 233{
234 struct hvc_struct *hp = container_of(port, struct hvc_struct, port); 234 struct hvc_struct *hp = container_of(kref, struct hvc_struct, kref);
235 unsigned long flags; 235 unsigned long flags;
236 236
237 spin_lock(&hvc_structs_lock); 237 spin_lock(&hvc_structs_lock);
@@ -245,20 +245,6 @@ 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
262/* 248/*
263 * hvc_instantiate() is an early console discovery method which locates 249 * hvc_instantiate() is an early console discovery method which locates
264 * consoles * prior to the vio subsystem discovering them. Hotplugged 250 * consoles * prior to the vio subsystem discovering them. Hotplugged
@@ -278,7 +264,7 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops)
278 /* make sure no no tty has been registered in this index */ 264 /* make sure no no tty has been registered in this index */
279 hp = hvc_get_by_index(index); 265 hp = hvc_get_by_index(index);
280 if (hp) { 266 if (hp) {
281 tty_port_put(&hp->port); 267 kref_put(&hp->kref, destroy_hvc_struct);
282 return -1; 268 return -1;
283 } 269 }
284 270
@@ -289,8 +275,12 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops)
289 if (last_hvc < index) 275 if (last_hvc < index)
290 last_hvc = index; 276 last_hvc = index;
291 277
292 /* check if we need to re-register the kernel console */ 278 /* if this index is what the user requested, then register
293 hvc_check_console(index); 279 * now (setup won't fail at this point). It's ok to just
280 * call register again if previously .setup failed.
281 */
282 if (index == hvc_console.index)
283 register_console(&hvc_console);
294 284
295 return 0; 285 return 0;
296} 286}
@@ -309,43 +299,34 @@ static void hvc_unthrottle(struct tty_struct *tty)
309 hvc_kick(); 299 hvc_kick();
310} 300}
311 301
312static int hvc_install(struct tty_driver *driver, struct tty_struct *tty)
313{
314 struct hvc_struct *hp;
315 int rc;
316
317 /* Auto increments kref reference if found. */
318 if (!(hp = hvc_get_by_index(tty->index)))
319 return -ENODEV;
320
321 tty->driver_data = hp;
322
323 rc = tty_port_install(&hp->port, driver, tty);
324 if (rc)
325 tty_port_put(&hp->port);
326 return rc;
327}
328
329/* 302/*
330 * The TTY interface won't be used until after the vio layer has exposed the vty 303 * The TTY interface won't be used until after the vio layer has exposed the vty
331 * adapter to the kernel. 304 * adapter to the kernel.
332 */ 305 */
333static int hvc_open(struct tty_struct *tty, struct file * filp) 306static int hvc_open(struct tty_struct *tty, struct file * filp)
334{ 307{
335 struct hvc_struct *hp = tty->driver_data; 308 struct hvc_struct *hp;
336 unsigned long flags; 309 unsigned long flags;
337 int rc = 0; 310 int rc = 0;
338 311
339 spin_lock_irqsave(&hp->port.lock, flags); 312 /* Auto increments kref reference if found. */
313 if (!(hp = hvc_get_by_index(tty->index)))
314 return -ENODEV;
315
316 spin_lock_irqsave(&hp->lock, flags);
340 /* Check and then increment for fast path open. */ 317 /* Check and then increment for fast path open. */
341 if (hp->port.count++ > 0) { 318 if (hp->count++ > 0) {
342 spin_unlock_irqrestore(&hp->port.lock, flags); 319 tty_kref_get(tty);
320 spin_unlock_irqrestore(&hp->lock, flags);
343 hvc_kick(); 321 hvc_kick();
344 return 0; 322 return 0;
345 } /* else count == 0 */ 323 } /* else count == 0 */
346 spin_unlock_irqrestore(&hp->port.lock, flags);
347 324
348 tty_port_tty_set(&hp->port, tty); 325 tty->driver_data = hp;
326
327 hp->tty = tty_kref_get(tty);
328
329 spin_unlock_irqrestore(&hp->lock, flags);
349 330
350 if (hp->ops->notifier_add) 331 if (hp->ops->notifier_add)
351 rc = hp->ops->notifier_add(hp, hp->data); 332 rc = hp->ops->notifier_add(hp, hp->data);
@@ -357,9 +338,12 @@ static int hvc_open(struct tty_struct *tty, struct file * filp)
357 * tty fields and return the kref reference. 338 * tty fields and return the kref reference.
358 */ 339 */
359 if (rc) { 340 if (rc) {
360 tty_port_tty_set(&hp->port, NULL); 341 spin_lock_irqsave(&hp->lock, flags);
342 hp->tty = NULL;
343 spin_unlock_irqrestore(&hp->lock, flags);
344 tty_kref_put(tty);
361 tty->driver_data = NULL; 345 tty->driver_data = NULL;
362 tty_port_put(&hp->port); 346 kref_put(&hp->kref, destroy_hvc_struct);
363 printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc); 347 printk(KERN_ERR "hvc_open: request_irq failed with rc %d.\n", rc);
364 } 348 }
365 /* Force wakeup of the polling thread */ 349 /* Force wakeup of the polling thread */
@@ -386,12 +370,12 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
386 370
387 hp = tty->driver_data; 371 hp = tty->driver_data;
388 372
389 spin_lock_irqsave(&hp->port.lock, flags); 373 spin_lock_irqsave(&hp->lock, flags);
390 374
391 if (--hp->port.count == 0) { 375 if (--hp->count == 0) {
392 spin_unlock_irqrestore(&hp->port.lock, flags);
393 /* We are done with the tty pointer now. */ 376 /* We are done with the tty pointer now. */
394 tty_port_tty_set(&hp->port, NULL); 377 hp->tty = NULL;
378 spin_unlock_irqrestore(&hp->lock, flags);
395 379
396 if (hp->ops->notifier_del) 380 if (hp->ops->notifier_del)
397 hp->ops->notifier_del(hp, hp->data); 381 hp->ops->notifier_del(hp, hp->data);
@@ -404,26 +388,23 @@ static void hvc_close(struct tty_struct *tty, struct file * filp)
404 * there is no buffered data otherwise sleeps on a wait queue 388 * there is no buffered data otherwise sleeps on a wait queue
405 * waking periodically to check chars_in_buffer(). 389 * waking periodically to check chars_in_buffer().
406 */ 390 */
407 tty_wait_until_sent_from_close(tty, HVC_CLOSE_WAIT); 391 tty_wait_until_sent(tty, HVC_CLOSE_WAIT);
408 } else { 392 } else {
409 if (hp->port.count < 0) 393 if (hp->count < 0)
410 printk(KERN_ERR "hvc_close %X: oops, count is %d\n", 394 printk(KERN_ERR "hvc_close %X: oops, count is %d\n",
411 hp->vtermno, hp->port.count); 395 hp->vtermno, hp->count);
412 spin_unlock_irqrestore(&hp->port.lock, flags); 396 spin_unlock_irqrestore(&hp->lock, flags);
413 } 397 }
414}
415 398
416static void hvc_cleanup(struct tty_struct *tty) 399 tty_kref_put(tty);
417{ 400 kref_put(&hp->kref, destroy_hvc_struct);
418 struct hvc_struct *hp = tty->driver_data;
419
420 tty_port_put(&hp->port);
421} 401}
422 402
423static void hvc_hangup(struct tty_struct *tty) 403static void hvc_hangup(struct tty_struct *tty)
424{ 404{
425 struct hvc_struct *hp = tty->driver_data; 405 struct hvc_struct *hp = tty->driver_data;
426 unsigned long flags; 406 unsigned long flags;
407 int temp_open_count;
427 408
428 if (!hp) 409 if (!hp)
429 return; 410 return;
@@ -431,26 +412,33 @@ static void hvc_hangup(struct tty_struct *tty)
431 /* cancel pending tty resize work */ 412 /* cancel pending tty resize work */
432 cancel_work_sync(&hp->tty_resize); 413 cancel_work_sync(&hp->tty_resize);
433 414
434 spin_lock_irqsave(&hp->port.lock, flags); 415 spin_lock_irqsave(&hp->lock, flags);
435 416
436 /* 417 /*
437 * The N_TTY line discipline has problems such that in a close vs 418 * The N_TTY line discipline has problems such that in a close vs
438 * open->hangup case this can be called after the final close so prevent 419 * open->hangup case this can be called after the final close so prevent
439 * that from happening for now. 420 * that from happening for now.
440 */ 421 */
441 if (hp->port.count <= 0) { 422 if (hp->count <= 0) {
442 spin_unlock_irqrestore(&hp->port.lock, flags); 423 spin_unlock_irqrestore(&hp->lock, flags);
443 return; 424 return;
444 } 425 }
445 426
446 hp->port.count = 0; 427 temp_open_count = hp->count;
447 spin_unlock_irqrestore(&hp->port.lock, flags); 428 hp->count = 0;
448 tty_port_tty_set(&hp->port, NULL);
449
450 hp->n_outbuf = 0; 429 hp->n_outbuf = 0;
430 hp->tty = NULL;
431
432 spin_unlock_irqrestore(&hp->lock, flags);
451 433
452 if (hp->ops->notifier_hangup) 434 if (hp->ops->notifier_hangup)
453 hp->ops->notifier_hangup(hp, hp->data); 435 hp->ops->notifier_hangup(hp, hp->data);
436
437 while(temp_open_count) {
438 --temp_open_count;
439 tty_kref_put(tty);
440 kref_put(&hp->kref, destroy_hvc_struct);
441 }
454} 442}
455 443
456/* 444/*
@@ -490,8 +478,7 @@ static int hvc_write(struct tty_struct *tty, const unsigned char *buf, int count
490 if (!hp) 478 if (!hp)
491 return -EPIPE; 479 return -EPIPE;
492 480
493 /* FIXME what's this (unprotected) check for? */ 481 if (hp->count <= 0)
494 if (hp->port.count <= 0)
495 return -EIO; 482 return -EIO;
496 483
497 spin_lock_irqsave(&hp->lock, flags); 484 spin_lock_irqsave(&hp->lock, flags);
@@ -539,12 +526,13 @@ static void hvc_set_winsz(struct work_struct *work)
539 526
540 hp = container_of(work, struct hvc_struct, tty_resize); 527 hp = container_of(work, struct hvc_struct, tty_resize);
541 528
542 tty = tty_port_tty_get(&hp->port);
543 if (!tty)
544 return;
545
546 spin_lock_irqsave(&hp->lock, hvc_flags); 529 spin_lock_irqsave(&hp->lock, hvc_flags);
547 ws = hp->ws; 530 if (!hp->tty) {
531 spin_unlock_irqrestore(&hp->lock, hvc_flags);
532 return;
533 }
534 ws = hp->ws;
535 tty = tty_kref_get(hp->tty);
548 spin_unlock_irqrestore(&hp->lock, hvc_flags); 536 spin_unlock_irqrestore(&hp->lock, hvc_flags);
549 537
550 tty_do_resize(tty, &ws); 538 tty_do_resize(tty, &ws);
@@ -561,7 +549,7 @@ static int hvc_write_room(struct tty_struct *tty)
561 struct hvc_struct *hp = tty->driver_data; 549 struct hvc_struct *hp = tty->driver_data;
562 550
563 if (!hp) 551 if (!hp)
564 return 0; 552 return -1;
565 553
566 return hp->outbuf_size - hp->n_outbuf; 554 return hp->outbuf_size - hp->n_outbuf;
567} 555}
@@ -613,7 +601,7 @@ int hvc_poll(struct hvc_struct *hp)
613 } 601 }
614 602
615 /* No tty attached, just skip */ 603 /* No tty attached, just skip */
616 tty = tty_port_tty_get(&hp->port); 604 tty = tty_kref_get(hp->tty);
617 if (tty == NULL) 605 if (tty == NULL)
618 goto bail; 606 goto bail;
619 607
@@ -693,7 +681,8 @@ int hvc_poll(struct hvc_struct *hp)
693 681
694 tty_flip_buffer_push(tty); 682 tty_flip_buffer_push(tty);
695 } 683 }
696 tty_kref_put(tty); 684 if (tty)
685 tty_kref_put(tty);
697 686
698 return poll_mask; 687 return poll_mask;
699} 688}
@@ -812,10 +801,8 @@ static void hvc_poll_put_char(struct tty_driver *driver, int line, char ch)
812#endif 801#endif
813 802
814static const struct tty_operations hvc_ops = { 803static const struct tty_operations hvc_ops = {
815 .install = hvc_install,
816 .open = hvc_open, 804 .open = hvc_open,
817 .close = hvc_close, 805 .close = hvc_close,
818 .cleanup = hvc_cleanup,
819 .write = hvc_write, 806 .write = hvc_write,
820 .hangup = hvc_hangup, 807 .hangup = hvc_hangup,
821 .unthrottle = hvc_unthrottle, 808 .unthrottle = hvc_unthrottle,
@@ -830,10 +817,6 @@ static const struct tty_operations hvc_ops = {
830#endif 817#endif
831}; 818};
832 819
833static const struct tty_port_operations hvc_port_ops = {
834 .destruct = hvc_port_destruct,
835};
836
837struct hvc_struct *hvc_alloc(uint32_t vtermno, int data, 820struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
838 const struct hv_ops *ops, 821 const struct hv_ops *ops,
839 int outbuf_size) 822 int outbuf_size)
@@ -859,8 +842,7 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
859 hp->outbuf_size = outbuf_size; 842 hp->outbuf_size = outbuf_size;
860 hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))]; 843 hp->outbuf = &((char *)hp)[ALIGN(sizeof(*hp), sizeof(long))];
861 844
862 tty_port_init(&hp->port); 845 kref_init(&hp->kref);
863 hp->port.ops = &hvc_port_ops;
864 846
865 INIT_WORK(&hp->tty_resize, hvc_set_winsz); 847 INIT_WORK(&hp->tty_resize, hvc_set_winsz);
866 spin_lock_init(&hp->lock); 848 spin_lock_init(&hp->lock);
@@ -880,15 +862,10 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
880 i = ++last_hvc; 862 i = ++last_hvc;
881 863
882 hp->index = i; 864 hp->index = i;
883 cons_ops[i] = ops;
884 vtermnos[i] = vtermno;
885 865
886 list_add_tail(&(hp->next), &hvc_structs); 866 list_add_tail(&(hp->next), &hvc_structs);
887 spin_unlock(&hvc_structs_lock); 867 spin_unlock(&hvc_structs_lock);
888 868
889 /* check if we need to re-register the kernel console */
890 hvc_check_console(i);
891
892 return hp; 869 return hp;
893} 870}
894EXPORT_SYMBOL_GPL(hvc_alloc); 871EXPORT_SYMBOL_GPL(hvc_alloc);
@@ -898,15 +875,11 @@ int hvc_remove(struct hvc_struct *hp)
898 unsigned long flags; 875 unsigned long flags;
899 struct tty_struct *tty; 876 struct tty_struct *tty;
900 877
901 tty = tty_port_tty_get(&hp->port);
902
903 spin_lock_irqsave(&hp->lock, flags); 878 spin_lock_irqsave(&hp->lock, flags);
904 if (hp->index < MAX_NR_HVC_CONSOLES) { 879 tty = tty_kref_get(hp->tty);
905 console_lock(); 880
881 if (hp->index < MAX_NR_HVC_CONSOLES)
906 vtermnos[hp->index] = -1; 882 vtermnos[hp->index] = -1;
907 cons_ops[hp->index] = NULL;
908 console_unlock();
909 }
910 883
911 /* Don't whack hp->irq because tty_hangup() will need to free the irq. */ 884 /* Don't whack hp->irq because tty_hangup() will need to free the irq. */
912 885
@@ -918,7 +891,7 @@ int hvc_remove(struct hvc_struct *hp)
918 * kref cause it to be removed, which will probably be the tty_vhangup 891 * kref cause it to be removed, which will probably be the tty_vhangup
919 * below. 892 * below.
920 */ 893 */
921 tty_port_put(&hp->port); 894 kref_put(&hp->kref, destroy_hvc_struct);
922 895
923 /* 896 /*
924 * This function call will auto chain call hvc_hangup. 897 * This function call will auto chain call hvc_hangup.
@@ -944,6 +917,7 @@ static int hvc_init(void)
944 goto out; 917 goto out;
945 } 918 }
946 919
920 drv->owner = THIS_MODULE;
947 drv->driver_name = "hvc"; 921 drv->driver_name = "hvc";
948 drv->name = "hvc"; 922 drv->name = "hvc";
949 drv->major = HVC_MAJOR; 923 drv->major = HVC_MAJOR;
diff --git a/drivers/tty/hvc/hvc_console.h b/drivers/tty/hvc/hvc_console.h
index 674d23cb919..c335a1492a5 100644
--- a/drivers/tty/hvc/hvc_console.h
+++ b/drivers/tty/hvc/hvc_console.h
@@ -46,9 +46,10 @@
46#define HVC_ALLOC_TTY_ADAPTERS 8 46#define HVC_ALLOC_TTY_ADAPTERS 8
47 47
48struct hvc_struct { 48struct hvc_struct {
49 struct tty_port port;
50 spinlock_t lock; 49 spinlock_t lock;
51 int index; 50 int index;
51 struct tty_struct *tty;
52 int count;
52 int do_wakeup; 53 int do_wakeup;
53 char *outbuf; 54 char *outbuf;
54 int outbuf_size; 55 int outbuf_size;
@@ -60,6 +61,7 @@ struct hvc_struct {
60 struct winsize ws; 61 struct winsize ws;
61 struct work_struct tty_resize; 62 struct work_struct tty_resize;
62 struct list_head next; 63 struct list_head next;
64 struct kref kref; /* ref count & hvc_struct lifetime */
63}; 65};
64 66
65/* implemented by a low level driver */ 67/* implemented by a low level driver */
diff --git a/drivers/tty/hvc/hvc_irq.c b/drivers/tty/hvc/hvc_irq.c
index c9adb0559f6..2623e177e8d 100644
--- a/drivers/tty/hvc/hvc_irq.c
+++ b/drivers/tty/hvc/hvc_irq.c
@@ -28,7 +28,7 @@ int notifier_add_irq(struct hvc_struct *hp, int irq)
28 hp->irq_requested = 0; 28 hp->irq_requested = 0;
29 return 0; 29 return 0;
30 } 30 }
31 rc = request_irq(irq, hvc_handle_interrupt, 0, 31 rc = request_irq(irq, hvc_handle_interrupt, IRQF_DISABLED,
32 "hvc_console", hp); 32 "hvc_console", hp);
33 if (!rc) 33 if (!rc)
34 hp->irq_requested = 1; 34 hp->irq_requested = 1;
diff --git a/drivers/tty/hvc/hvc_opal.c b/drivers/tty/hvc/hvc_opal.c
deleted file mode 100644
index cd69b48f6df..00000000000
--- a/drivers/tty/hvc/hvc_opal.c
+++ /dev/null
@@ -1,425 +0,0 @@
1/*
2 * opal driver interface to hvc_console.c
3 *
4 * Copyright 2011 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#undef DEBUG
23
24#include <linux/types.h>
25#include <linux/init.h>
26#include <linux/delay.h>
27#include <linux/slab.h>
28#include <linux/console.h>
29#include <linux/of.h>
30#include <linux/of_platform.h>
31#include <linux/export.h>
32
33#include <asm/hvconsole.h>
34#include <asm/prom.h>
35#include <asm/firmware.h>
36#include <asm/hvsi.h>
37#include <asm/udbg.h>
38#include <asm/opal.h>
39
40#include "hvc_console.h"
41
42static const char hvc_opal_name[] = "hvc_opal";
43
44static struct of_device_id hvc_opal_match[] = {
45 { .name = "serial", .compatible = "ibm,opal-console-raw" },
46 { .name = "serial", .compatible = "ibm,opal-console-hvsi" },
47 { },
48};
49
50typedef enum hv_protocol {
51 HV_PROTOCOL_RAW,
52 HV_PROTOCOL_HVSI
53} hv_protocol_t;
54
55struct hvc_opal_priv {
56 hv_protocol_t proto; /* Raw data or HVSI packets */
57 struct hvsi_priv hvsi; /* HVSI specific data */
58};
59static struct hvc_opal_priv *hvc_opal_privs[MAX_NR_HVC_CONSOLES];
60
61/* For early boot console */
62static struct hvc_opal_priv hvc_opal_boot_priv;
63static u32 hvc_opal_boot_termno;
64
65static const struct hv_ops hvc_opal_raw_ops = {
66 .get_chars = opal_get_chars,
67 .put_chars = opal_put_chars,
68 .notifier_add = notifier_add_irq,
69 .notifier_del = notifier_del_irq,
70 .notifier_hangup = notifier_hangup_irq,
71};
72
73static int hvc_opal_hvsi_get_chars(uint32_t vtermno, char *buf, int count)
74{
75 struct hvc_opal_priv *pv = hvc_opal_privs[vtermno];
76
77 if (WARN_ON(!pv))
78 return -ENODEV;
79
80 return hvsilib_get_chars(&pv->hvsi, buf, count);
81}
82
83static int hvc_opal_hvsi_put_chars(uint32_t vtermno, const char *buf, int count)
84{
85 struct hvc_opal_priv *pv = hvc_opal_privs[vtermno];
86
87 if (WARN_ON(!pv))
88 return -ENODEV;
89
90 return hvsilib_put_chars(&pv->hvsi, buf, count);
91}
92
93static int hvc_opal_hvsi_open(struct hvc_struct *hp, int data)
94{
95 struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
96 int rc;
97
98 pr_devel("HVSI@%x: do open !\n", hp->vtermno);
99
100 rc = notifier_add_irq(hp, data);
101 if (rc)
102 return rc;
103
104 return hvsilib_open(&pv->hvsi, hp);
105}
106
107static void hvc_opal_hvsi_close(struct hvc_struct *hp, int data)
108{
109 struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
110
111 pr_devel("HVSI@%x: do close !\n", hp->vtermno);
112
113 hvsilib_close(&pv->hvsi, hp);
114
115 notifier_del_irq(hp, data);
116}
117
118void hvc_opal_hvsi_hangup(struct hvc_struct *hp, int data)
119{
120 struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
121
122 pr_devel("HVSI@%x: do hangup !\n", hp->vtermno);
123
124 hvsilib_close(&pv->hvsi, hp);
125
126 notifier_hangup_irq(hp, data);
127}
128
129static int hvc_opal_hvsi_tiocmget(struct hvc_struct *hp)
130{
131 struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
132
133 if (!pv)
134 return -EINVAL;
135 return pv->hvsi.mctrl;
136}
137
138static int hvc_opal_hvsi_tiocmset(struct hvc_struct *hp, unsigned int set,
139 unsigned int clear)
140{
141 struct hvc_opal_priv *pv = hvc_opal_privs[hp->vtermno];
142
143 pr_devel("HVSI@%x: Set modem control, set=%x,clr=%x\n",
144 hp->vtermno, set, clear);
145
146 if (set & TIOCM_DTR)
147 hvsilib_write_mctrl(&pv->hvsi, 1);
148 else if (clear & TIOCM_DTR)
149 hvsilib_write_mctrl(&pv->hvsi, 0);
150
151 return 0;
152}
153
154static const struct hv_ops hvc_opal_hvsi_ops = {
155 .get_chars = hvc_opal_hvsi_get_chars,
156 .put_chars = hvc_opal_hvsi_put_chars,
157 .notifier_add = hvc_opal_hvsi_open,
158 .notifier_del = hvc_opal_hvsi_close,
159 .notifier_hangup = hvc_opal_hvsi_hangup,
160 .tiocmget = hvc_opal_hvsi_tiocmget,
161 .tiocmset = hvc_opal_hvsi_tiocmset,
162};
163
164static int hvc_opal_probe(struct platform_device *dev)
165{
166 const struct hv_ops *ops;
167 struct hvc_struct *hp;
168 struct hvc_opal_priv *pv;
169 hv_protocol_t proto;
170 unsigned int termno, boot = 0;
171 const __be32 *reg;
172
173 if (of_device_is_compatible(dev->dev.of_node, "ibm,opal-console-raw")) {
174 proto = HV_PROTOCOL_RAW;
175 ops = &hvc_opal_raw_ops;
176 } else if (of_device_is_compatible(dev->dev.of_node,
177 "ibm,opal-console-hvsi")) {
178 proto = HV_PROTOCOL_HVSI;
179 ops = &hvc_opal_hvsi_ops;
180 } else {
181 pr_err("hvc_opal: Unknown protocol for %s\n",
182 dev->dev.of_node->full_name);
183 return -ENXIO;
184 }
185
186 reg = of_get_property(dev->dev.of_node, "reg", NULL);
187 termno = reg ? be32_to_cpup(reg) : 0;
188
189 /* Is it our boot one ? */
190 if (hvc_opal_privs[termno] == &hvc_opal_boot_priv) {
191 pv = hvc_opal_privs[termno];
192 boot = 1;
193 } else if (hvc_opal_privs[termno] == NULL) {
194 pv = kzalloc(sizeof(struct hvc_opal_priv), GFP_KERNEL);
195 if (!pv)
196 return -ENOMEM;
197 pv->proto = proto;
198 hvc_opal_privs[termno] = pv;
199 if (proto == HV_PROTOCOL_HVSI)
200 hvsilib_init(&pv->hvsi, opal_get_chars, opal_put_chars,
201 termno, 0);
202
203 /* Instanciate now to establish a mapping index==vtermno */
204 hvc_instantiate(termno, termno, ops);
205 } else {
206 pr_err("hvc_opal: Device %s has duplicate terminal number #%d\n",
207 dev->dev.of_node->full_name, termno);
208 return -ENXIO;
209 }
210
211 pr_info("hvc%d: %s protocol on %s%s\n", termno,
212 proto == HV_PROTOCOL_RAW ? "raw" : "hvsi",
213 dev->dev.of_node->full_name,
214 boot ? " (boot console)" : "");
215
216 /* We don't do IRQ yet */
217 hp = hvc_alloc(termno, 0, ops, MAX_VIO_PUT_CHARS);
218 if (IS_ERR(hp))
219 return PTR_ERR(hp);
220 dev_set_drvdata(&dev->dev, hp);
221
222 return 0;
223}
224
225static int hvc_opal_remove(struct platform_device *dev)
226{
227 struct hvc_struct *hp = dev_get_drvdata(&dev->dev);
228 int rc, termno;
229
230 termno = hp->vtermno;
231 rc = hvc_remove(hp);
232 if (rc == 0) {
233 if (hvc_opal_privs[termno] != &hvc_opal_boot_priv)
234 kfree(hvc_opal_privs[termno]);
235 hvc_opal_privs[termno] = NULL;
236 }
237 return rc;
238}
239
240static struct platform_driver hvc_opal_driver = {
241 .probe = hvc_opal_probe,
242 .remove = hvc_opal_remove,
243 .driver = {
244 .name = hvc_opal_name,
245 .owner = THIS_MODULE,
246 .of_match_table = hvc_opal_match,
247 }
248};
249
250static int __init hvc_opal_init(void)
251{
252 if (!firmware_has_feature(FW_FEATURE_OPAL))
253 return -ENODEV;
254
255 /* Register as a vio device to receive callbacks */
256 return platform_driver_register(&hvc_opal_driver);
257}
258module_init(hvc_opal_init);
259
260static void __exit hvc_opal_exit(void)
261{
262 platform_driver_unregister(&hvc_opal_driver);
263}
264module_exit(hvc_opal_exit);
265
266static void udbg_opal_putc(char c)
267{
268 unsigned int termno = hvc_opal_boot_termno;
269 int count = -1;
270
271 if (c == '\n')
272 udbg_opal_putc('\r');
273
274 do {
275 switch(hvc_opal_boot_priv.proto) {
276 case HV_PROTOCOL_RAW:
277 count = opal_put_chars(termno, &c, 1);
278 break;
279 case HV_PROTOCOL_HVSI:
280 count = hvc_opal_hvsi_put_chars(termno, &c, 1);
281 break;
282 }
283 } while(count == 0 || count == -EAGAIN);
284}
285
286static int udbg_opal_getc_poll(void)
287{
288 unsigned int termno = hvc_opal_boot_termno;
289 int rc = 0;
290 char c;
291
292 switch(hvc_opal_boot_priv.proto) {
293 case HV_PROTOCOL_RAW:
294 rc = opal_get_chars(termno, &c, 1);
295 break;
296 case HV_PROTOCOL_HVSI:
297 rc = hvc_opal_hvsi_get_chars(termno, &c, 1);
298 break;
299 }
300 if (!rc)
301 return -1;
302 return c;
303}
304
305static int udbg_opal_getc(void)
306{
307 int ch;
308 for (;;) {
309 ch = udbg_opal_getc_poll();
310 if (ch == -1) {
311 /* This shouldn't be needed...but... */
312 volatile unsigned long delay;
313 for (delay=0; delay < 2000000; delay++)
314 ;
315 } else {
316 return ch;
317 }
318 }
319}
320
321static void udbg_init_opal_common(void)
322{
323 udbg_putc = udbg_opal_putc;
324 udbg_getc = udbg_opal_getc;
325 udbg_getc_poll = udbg_opal_getc_poll;
326 tb_ticks_per_usec = 0x200; /* Make udelay not suck */
327}
328
329void __init hvc_opal_init_early(void)
330{
331 struct device_node *stdout_node = NULL;
332 const u32 *termno;
333 const char *name = NULL;
334 const struct hv_ops *ops;
335 u32 index;
336
337 /* find the boot console from /chosen/stdout */
338 if (of_chosen)
339 name = of_get_property(of_chosen, "linux,stdout-path", NULL);
340 if (name) {
341 stdout_node = of_find_node_by_path(name);
342 if (!stdout_node) {
343 pr_err("hvc_opal: Failed to locate default console!\n");
344 return;
345 }
346 } else {
347 struct device_node *opal, *np;
348
349 /* Current OPAL takeover doesn't provide the stdout
350 * path, so we hard wire it
351 */
352 opal = of_find_node_by_path("/ibm,opal/consoles");
353 if (opal)
354 pr_devel("hvc_opal: Found consoles in new location\n");
355 if (!opal) {
356 opal = of_find_node_by_path("/ibm,opal");
357 if (opal)
358 pr_devel("hvc_opal: "
359 "Found consoles in old location\n");
360 }
361 if (!opal)
362 return;
363 for_each_child_of_node(opal, np) {
364 if (!strcmp(np->name, "serial")) {
365 stdout_node = np;
366 break;
367 }
368 }
369 of_node_put(opal);
370 }
371 if (!stdout_node)
372 return;
373 termno = of_get_property(stdout_node, "reg", NULL);
374 index = termno ? *termno : 0;
375 if (index >= MAX_NR_HVC_CONSOLES)
376 return;
377 hvc_opal_privs[index] = &hvc_opal_boot_priv;
378
379 /* Check the protocol */
380 if (of_device_is_compatible(stdout_node, "ibm,opal-console-raw")) {
381 hvc_opal_boot_priv.proto = HV_PROTOCOL_RAW;
382 ops = &hvc_opal_raw_ops;
383 pr_devel("hvc_opal: Found RAW console\n");
384 }
385 else if (of_device_is_compatible(stdout_node,"ibm,opal-console-hvsi")) {
386 hvc_opal_boot_priv.proto = HV_PROTOCOL_HVSI;
387 ops = &hvc_opal_hvsi_ops;
388 hvsilib_init(&hvc_opal_boot_priv.hvsi, opal_get_chars,
389 opal_put_chars, index, 1);
390 /* HVSI, perform the handshake now */
391 hvsilib_establish(&hvc_opal_boot_priv.hvsi);
392 pr_devel("hvc_opal: Found HVSI console\n");
393 } else
394 goto out;
395 hvc_opal_boot_termno = index;
396 udbg_init_opal_common();
397 add_preferred_console("hvc", index, NULL);
398 hvc_instantiate(index, index, ops);
399out:
400 of_node_put(stdout_node);
401}
402
403#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL_RAW
404void __init udbg_init_debug_opal_raw(void)
405{
406 u32 index = CONFIG_PPC_EARLY_DEBUG_OPAL_VTERMNO;
407 hvc_opal_privs[index] = &hvc_opal_boot_priv;
408 hvc_opal_boot_priv.proto = HV_PROTOCOL_RAW;
409 hvc_opal_boot_termno = index;
410 udbg_init_opal_common();
411}
412#endif /* CONFIG_PPC_EARLY_DEBUG_OPAL_RAW */
413
414#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI
415void __init udbg_init_debug_opal_hvsi(void)
416{
417 u32 index = CONFIG_PPC_EARLY_DEBUG_OPAL_VTERMNO;
418 hvc_opal_privs[index] = &hvc_opal_boot_priv;
419 hvc_opal_boot_termno = index;
420 udbg_init_opal_common();
421 hvsilib_init(&hvc_opal_boot_priv.hvsi, opal_get_chars, opal_put_chars,
422 index, 1);
423 hvsilib_establish(&hvc_opal_boot_priv.hvsi);
424}
425#endif /* CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI */
diff --git a/drivers/tty/hvc/hvc_rtas.c b/drivers/tty/hvc/hvc_rtas.c
index 0069bb86ba4..61c4a61558d 100644
--- a/drivers/tty/hvc/hvc_rtas.c
+++ b/drivers/tty/hvc/hvc_rtas.c
@@ -94,7 +94,7 @@ static int __init hvc_rtas_init(void)
94 94
95 /* Allocate an hvc_struct for the console device we instantiated 95 /* Allocate an hvc_struct for the console device we instantiated
96 * earlier. Save off hp so that we can return it on exit */ 96 * earlier. Save off hp so that we can return it on exit */
97 hp = hvc_alloc(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops, 16); 97 hp = hvc_alloc(hvc_rtas_cookie, NO_IRQ, &hvc_rtas_get_put_ops, 16);
98 if (IS_ERR(hp)) 98 if (IS_ERR(hp))
99 return PTR_ERR(hp); 99 return PTR_ERR(hp);
100 100
diff --git a/drivers/tty/hvc/hvc_udbg.c b/drivers/tty/hvc/hvc_udbg.c
index 72228276fe3..b0957e61a7b 100644
--- a/drivers/tty/hvc/hvc_udbg.c
+++ b/drivers/tty/hvc/hvc_udbg.c
@@ -36,7 +36,7 @@ static int hvc_udbg_put(uint32_t vtermno, const char *buf, int count)
36{ 36{
37 int i; 37 int i;
38 38
39 for (i = 0; i < count && udbg_putc; i++) 39 for (i = 0; i < count; i++)
40 udbg_putc(buf[i]); 40 udbg_putc(buf[i]);
41 41
42 return i; 42 return i;
@@ -67,12 +67,9 @@ static int __init hvc_udbg_init(void)
67{ 67{
68 struct hvc_struct *hp; 68 struct hvc_struct *hp;
69 69
70 if (!udbg_putc)
71 return -ENODEV;
72
73 BUG_ON(hvc_udbg_dev); 70 BUG_ON(hvc_udbg_dev);
74 71
75 hp = hvc_alloc(0, 0, &hvc_udbg_ops, 16); 72 hp = hvc_alloc(0, NO_IRQ, &hvc_udbg_ops, 16);
76 if (IS_ERR(hp)) 73 if (IS_ERR(hp))
77 return PTR_ERR(hp); 74 return PTR_ERR(hp);
78 75
@@ -91,9 +88,6 @@ module_exit(hvc_udbg_exit);
91 88
92static int __init hvc_udbg_console_init(void) 89static int __init hvc_udbg_console_init(void)
93{ 90{
94 if (!udbg_putc)
95 return -ENODEV;
96
97 hvc_instantiate(0, 0, &hvc_udbg_ops); 91 hvc_instantiate(0, 0, &hvc_udbg_ops);
98 add_preferred_console("hvc", 0, NULL); 92 add_preferred_console("hvc", 0, NULL);
99 93
diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c
index 0c629807610..130aace67f3 100644
--- a/drivers/tty/hvc/hvc_vio.c
+++ b/drivers/tty/hvc/hvc_vio.c
@@ -41,11 +41,11 @@
41#include <linux/delay.h> 41#include <linux/delay.h>
42#include <linux/slab.h> 42#include <linux/slab.h>
43#include <linux/console.h> 43#include <linux/console.h>
44#include <linux/module.h>
45 44
46#include <asm/hvconsole.h> 45#include <asm/hvconsole.h>
47#include <asm/vio.h> 46#include <asm/vio.h>
48#include <asm/prom.h> 47#include <asm/prom.h>
48#include <asm/firmware.h>
49#include <asm/hvsi.h> 49#include <asm/hvsi.h>
50#include <asm/udbg.h> 50#include <asm/udbg.h>
51 51
@@ -53,7 +53,7 @@
53 53
54static const char hvc_driver_name[] = "hvc_console"; 54static const char hvc_driver_name[] = "hvc_console";
55 55
56static struct vio_device_id hvc_driver_table[] = { 56static struct vio_device_id hvc_driver_table[] __devinitdata = {
57 {"serial", "hvterm1"}, 57 {"serial", "hvterm1"},
58#ifndef HVC_OLD_HVSI 58#ifndef HVC_OLD_HVSI
59 {"serial", "hvterm-protocol"}, 59 {"serial", "hvterm-protocol"},
@@ -230,70 +230,7 @@ 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) 233static int __devinit hvc_vio_probe(struct vio_dev *vdev,
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
296static int hvc_vio_probe(struct vio_dev *vdev,
297 const struct vio_device_id *id) 234 const struct vio_device_id *id)
298{ 235{
299 const struct hv_ops *ops; 236 const struct hv_ops *ops;
@@ -313,7 +250,7 @@ static int hvc_vio_probe(struct vio_dev *vdev,
313 proto = HV_PROTOCOL_HVSI; 250 proto = HV_PROTOCOL_HVSI;
314 ops = &hvterm_hvsi_ops; 251 ops = &hvterm_hvsi_ops;
315 } else { 252 } else {
316 pr_err("hvc_vio: Unknown protocol for %s\n", vdev->dev.of_node->full_name); 253 pr_err("hvc_vio: Unkown protocol for %s\n", vdev->dev.of_node->full_name);
317 return -ENXIO; 254 return -ENXIO;
318 } 255 }
319 256
@@ -352,17 +289,10 @@ static int hvc_vio_probe(struct vio_dev *vdev,
352 return PTR_ERR(hp); 289 return PTR_ERR(hp);
353 dev_set_drvdata(&vdev->dev, hp); 290 dev_set_drvdata(&vdev->dev, hp);
354 291
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
362 return 0; 292 return 0;
363} 293}
364 294
365static int hvc_vio_remove(struct vio_dev *vdev) 295static int __devexit hvc_vio_remove(struct vio_dev *vdev)
366{ 296{
367 struct hvc_struct *hp = dev_get_drvdata(&vdev->dev); 297 struct hvc_struct *hp = dev_get_drvdata(&vdev->dev);
368 int rc, termno; 298 int rc, termno;
@@ -380,14 +310,20 @@ static int hvc_vio_remove(struct vio_dev *vdev)
380static struct vio_driver hvc_vio_driver = { 310static struct vio_driver hvc_vio_driver = {
381 .id_table = hvc_driver_table, 311 .id_table = hvc_driver_table,
382 .probe = hvc_vio_probe, 312 .probe = hvc_vio_probe,
383 .remove = hvc_vio_remove, 313 .remove = __devexit_p(hvc_vio_remove),
384 .name = hvc_driver_name, 314 .driver = {
315 .name = hvc_driver_name,
316 .owner = THIS_MODULE,
317 }
385}; 318};
386 319
387static int __init hvc_vio_init(void) 320static int __init hvc_vio_init(void)
388{ 321{
389 int rc; 322 int rc;
390 323
324 if (firmware_has_feature(FW_FEATURE_ISERIES))
325 return -EIO;
326
391 /* Register as a vio device to receive callbacks */ 327 /* Register as a vio device to receive callbacks */
392 rc = vio_register_driver(&hvc_vio_driver); 328 rc = vio_register_driver(&hvc_vio_driver);
393 329
@@ -401,6 +337,59 @@ static void __exit hvc_vio_exit(void)
401} 337}
402module_exit(hvc_vio_exit); 338module_exit(hvc_vio_exit);
403 339
340static void udbg_hvc_putc(char c)
341{
342 int count = -1;
343
344 if (c == '\n')
345 udbg_hvc_putc('\r');
346
347 do {
348 switch(hvterm_priv0.proto) {
349 case HV_PROTOCOL_RAW:
350 count = hvterm_raw_put_chars(0, &c, 1);
351 break;
352 case HV_PROTOCOL_HVSI:
353 count = hvterm_hvsi_put_chars(0, &c, 1);
354 break;
355 }
356 } while(count == 0);
357}
358
359static int udbg_hvc_getc_poll(void)
360{
361 int rc = 0;
362 char c;
363
364 switch(hvterm_priv0.proto) {
365 case HV_PROTOCOL_RAW:
366 rc = hvterm_raw_get_chars(0, &c, 1);
367 break;
368 case HV_PROTOCOL_HVSI:
369 rc = hvterm_hvsi_get_chars(0, &c, 1);
370 break;
371 }
372 if (!rc)
373 return -1;
374 return c;
375}
376
377static int udbg_hvc_getc(void)
378{
379 int ch;
380 for (;;) {
381 ch = udbg_hvc_getc_poll();
382 if (ch == -1) {
383 /* This shouldn't be needed...but... */
384 volatile unsigned long delay;
385 for (delay=0; delay < 2000000; delay++)
386 ;
387 } else {
388 return ch;
389 }
390 }
391}
392
404void __init hvc_vio_init_early(void) 393void __init hvc_vio_init_early(void)
405{ 394{
406 struct device_node *stdout_node; 395 struct device_node *stdout_node;
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
index 19843ec3f80..52fdf60bdbe 100644
--- a/drivers/tty/hvc/hvc_xen.c
+++ b/drivers/tty/hvc/hvc_xen.c
@@ -21,78 +21,46 @@
21#include <linux/console.h> 21#include <linux/console.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/err.h> 23#include <linux/err.h>
24#include <linux/irq.h>
25#include <linux/init.h> 24#include <linux/init.h>
26#include <linux/types.h> 25#include <linux/types.h>
27#include <linux/list.h>
28 26
29#include <asm/io.h>
30#include <asm/xen/hypervisor.h> 27#include <asm/xen/hypervisor.h>
31 28
32#include <xen/xen.h> 29#include <xen/xen.h>
33#include <xen/interface/xen.h>
34#include <xen/hvm.h>
35#include <xen/grant_table.h>
36#include <xen/page.h> 30#include <xen/page.h>
37#include <xen/events.h> 31#include <xen/events.h>
38#include <xen/interface/io/console.h> 32#include <xen/interface/io/console.h>
39#include <xen/interface/sched.h>
40#include <xen/hvc-console.h> 33#include <xen/hvc-console.h>
41#include <xen/xenbus.h>
42 34
43#include "hvc_console.h" 35#include "hvc_console.h"
44 36
45#define HVC_COOKIE 0x58656e /* "Xen" in hex */ 37#define HVC_COOKIE 0x58656e /* "Xen" in hex */
46 38
47struct xencons_info { 39static struct hvc_struct *hvc;
48 struct list_head list; 40static int xencons_irq;
49 struct xenbus_device *xbdev;
50 struct xencons_interface *intf;
51 unsigned int evtchn;
52 struct hvc_struct *hvc;
53 int irq;
54 int vtermno;
55 grant_ref_t gntref;
56};
57
58static LIST_HEAD(xenconsoles);
59static DEFINE_SPINLOCK(xencons_lock);
60 41
61/* ------------------------------------------------------------------ */ 42/* ------------------------------------------------------------------ */
62 43
63static struct xencons_info *vtermno_to_xencons(int vtermno) 44static unsigned long console_pfn = ~0ul;
64{
65 struct xencons_info *entry, *n, *ret = NULL;
66
67 if (list_empty(&xenconsoles))
68 return NULL;
69 45
70 list_for_each_entry_safe(entry, n, &xenconsoles, list) { 46static inline struct xencons_interface *xencons_interface(void)
71 if (entry->vtermno == vtermno) {
72 ret = entry;
73 break;
74 }
75 }
76
77 return ret;
78}
79
80static inline int xenbus_devid_to_vtermno(int devid)
81{ 47{
82 return devid + HVC_COOKIE; 48 if (console_pfn == ~0ul)
49 return mfn_to_virt(xen_start_info->console.domU.mfn);
50 else
51 return __va(console_pfn << PAGE_SHIFT);
83} 52}
84 53
85static inline void notify_daemon(struct xencons_info *cons) 54static inline void notify_daemon(void)
86{ 55{
87 /* Use evtchn: this is called early, before irq is set up. */ 56 /* Use evtchn: this is called early, before irq is set up. */
88 notify_remote_via_evtchn(cons->evtchn); 57 notify_remote_via_evtchn(xen_start_info->console.domU.evtchn);
89} 58}
90 59
91static int __write_console(struct xencons_info *xencons, 60static int __write_console(const char *data, int len)
92 const char *data, int len)
93{ 61{
62 struct xencons_interface *intf = xencons_interface();
94 XENCONS_RING_IDX cons, prod; 63 XENCONS_RING_IDX cons, prod;
95 struct xencons_interface *intf = xencons->intf;
96 int sent = 0; 64 int sent = 0;
97 65
98 cons = intf->out_cons; 66 cons = intf->out_cons;
@@ -107,16 +75,13 @@ static int __write_console(struct xencons_info *xencons,
107 intf->out_prod = prod; 75 intf->out_prod = prod;
108 76
109 if (sent) 77 if (sent)
110 notify_daemon(xencons); 78 notify_daemon();
111 return sent; 79 return sent;
112} 80}
113 81
114static int domU_write_console(uint32_t vtermno, const char *data, int len) 82static int domU_write_console(uint32_t vtermno, const char *data, int len)
115{ 83{
116 int ret = len; 84 int ret = len;
117 struct xencons_info *cons = vtermno_to_xencons(vtermno);
118 if (cons == NULL)
119 return -EINVAL;
120 85
121 /* 86 /*
122 * Make sure the whole buffer is emitted, polling if 87 * Make sure the whole buffer is emitted, polling if
@@ -125,7 +90,7 @@ static int domU_write_console(uint32_t vtermno, const char *data, int len)
125 * kernel is crippled. 90 * kernel is crippled.
126 */ 91 */
127 while (len) { 92 while (len) {
128 int sent = __write_console(cons, data, len); 93 int sent = __write_console(data, len);
129 94
130 data += sent; 95 data += sent;
131 len -= sent; 96 len -= sent;
@@ -139,13 +104,9 @@ static int domU_write_console(uint32_t vtermno, const char *data, int len)
139 104
140static int domU_read_console(uint32_t vtermno, char *buf, int len) 105static int domU_read_console(uint32_t vtermno, char *buf, int len)
141{ 106{
142 struct xencons_interface *intf; 107 struct xencons_interface *intf = xencons_interface();
143 XENCONS_RING_IDX cons, prod; 108 XENCONS_RING_IDX cons, prod;
144 int recv = 0; 109 int recv = 0;
145 struct xencons_info *xencons = vtermno_to_xencons(vtermno);
146 if (xencons == NULL)
147 return -EINVAL;
148 intf = xencons->intf;
149 110
150 cons = intf->in_cons; 111 cons = intf->in_cons;
151 prod = intf->in_prod; 112 prod = intf->in_prod;
@@ -158,7 +119,7 @@ static int domU_read_console(uint32_t vtermno, char *buf, int len)
158 mb(); /* read ring before consuming */ 119 mb(); /* read ring before consuming */
159 intf->in_cons = cons; 120 intf->in_cons = cons;
160 121
161 notify_daemon(xencons); 122 notify_daemon();
162 return recv; 123 return recv;
163} 124}
164 125
@@ -196,410 +157,68 @@ static struct hv_ops dom0_hvc_ops = {
196 .notifier_hangup = notifier_hangup_irq, 157 .notifier_hangup = notifier_hangup_irq,
197}; 158};
198 159
199static int xen_hvm_console_init(void) 160static int __init xen_hvc_init(void)
200{
201 int r;
202 uint64_t v = 0;
203 unsigned long mfn;
204 struct xencons_info *info;
205
206 if (!xen_hvm_domain())
207 return -ENODEV;
208
209 info = vtermno_to_xencons(HVC_COOKIE);
210 if (!info) {
211 info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL | __GFP_ZERO);
212 if (!info)
213 return -ENOMEM;
214 } else if (info->intf != NULL) {
215 /* already configured */
216 return 0;
217 }
218 /*
219 * If the toolstack (or the hypervisor) hasn't set these values, the
220 * default value is 0. Even though mfn = 0 and evtchn = 0 are
221 * theoretically correct values, in practice they never are and they
222 * mean that a legacy toolstack hasn't initialized the pv console correctly.
223 */
224 r = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v);
225 if (r < 0 || v == 0)
226 goto err;
227 info->evtchn = v;
228 v = 0;
229 r = hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v);
230 if (r < 0 || v == 0)
231 goto err;
232 mfn = v;
233 info->intf = ioremap(mfn << PAGE_SHIFT, PAGE_SIZE);
234 if (info->intf == NULL)
235 goto err;
236 info->vtermno = HVC_COOKIE;
237
238 spin_lock(&xencons_lock);
239 list_add_tail(&info->list, &xenconsoles);
240 spin_unlock(&xencons_lock);
241
242 return 0;
243err:
244 kfree(info);
245 return -ENODEV;
246}
247
248static int xen_pv_console_init(void)
249{ 161{
250 struct xencons_info *info; 162 struct hvc_struct *hp;
163 struct hv_ops *ops;
251 164
252 if (!xen_pv_domain()) 165 if (!xen_pv_domain())
253 return -ENODEV; 166 return -ENODEV;
254 167
255 if (!xen_start_info->console.domU.evtchn) 168 if (xen_initial_domain()) {
256 return -ENODEV; 169 ops = &dom0_hvc_ops;
257 170 xencons_irq = bind_virq_to_irq(VIRQ_CONSOLE, 0);
258 info = vtermno_to_xencons(HVC_COOKIE); 171 } else {
259 if (!info) { 172 if (!xen_start_info->console.domU.evtchn)
260 info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL | __GFP_ZERO); 173 return -ENODEV;
261 if (!info)
262 return -ENOMEM;
263 } else if (info->intf != NULL) {
264 /* already configured */
265 return 0;
266 }
267 info->evtchn = xen_start_info->console.domU.evtchn;
268 info->intf = mfn_to_virt(xen_start_info->console.domU.mfn);
269 info->vtermno = HVC_COOKIE;
270
271 spin_lock(&xencons_lock);
272 list_add_tail(&info->list, &xenconsoles);
273 spin_unlock(&xencons_lock);
274
275 return 0;
276}
277
278static int xen_initial_domain_console_init(void)
279{
280 struct xencons_info *info;
281
282 if (!xen_initial_domain())
283 return -ENODEV;
284
285 info = vtermno_to_xencons(HVC_COOKIE);
286 if (!info) {
287 info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL | __GFP_ZERO);
288 if (!info)
289 return -ENOMEM;
290 }
291
292 info->irq = bind_virq_to_irq(VIRQ_CONSOLE, 0);
293 info->vtermno = HVC_COOKIE;
294
295 spin_lock(&xencons_lock);
296 list_add_tail(&info->list, &xenconsoles);
297 spin_unlock(&xencons_lock);
298
299 return 0;
300}
301
302void xen_console_resume(void)
303{
304 struct xencons_info *info = vtermno_to_xencons(HVC_COOKIE);
305 if (info != NULL && info->irq)
306 rebind_evtchn_irq(info->evtchn, info->irq);
307}
308
309static void xencons_disconnect_backend(struct xencons_info *info)
310{
311 if (info->irq > 0)
312 unbind_from_irqhandler(info->irq, NULL);
313 info->irq = 0;
314 if (info->evtchn > 0)
315 xenbus_free_evtchn(info->xbdev, info->evtchn);
316 info->evtchn = 0;
317 if (info->gntref > 0)
318 gnttab_free_grant_references(info->gntref);
319 info->gntref = 0;
320 if (info->hvc != NULL)
321 hvc_remove(info->hvc);
322 info->hvc = NULL;
323}
324
325static void xencons_free(struct xencons_info *info)
326{
327 free_page((unsigned long)info->intf);
328 info->intf = NULL;
329 info->vtermno = 0;
330 kfree(info);
331}
332 174
333static int xen_console_remove(struct xencons_info *info) 175 ops = &domU_hvc_ops;
334{ 176 xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn);
335 xencons_disconnect_backend(info);
336 spin_lock(&xencons_lock);
337 list_del(&info->list);
338 spin_unlock(&xencons_lock);
339 if (info->xbdev != NULL)
340 xencons_free(info);
341 else {
342 if (xen_hvm_domain())
343 iounmap(info->intf);
344 kfree(info);
345 } 177 }
346 return 0; 178 if (xencons_irq < 0)
347} 179 xencons_irq = 0; /* NO_IRQ */
348
349#ifdef CONFIG_HVC_XEN_FRONTEND
350static struct xenbus_driver xencons_driver;
351
352static int xencons_remove(struct xenbus_device *dev)
353{
354 return xen_console_remove(dev_get_drvdata(&dev->dev));
355}
356
357static int xencons_connect_backend(struct xenbus_device *dev,
358 struct xencons_info *info)
359{
360 int ret, evtchn, devid, ref, irq;
361 struct xenbus_transaction xbt;
362 grant_ref_t gref_head;
363 unsigned long mfn;
364
365 ret = xenbus_alloc_evtchn(dev, &evtchn);
366 if (ret)
367 return ret;
368 info->evtchn = evtchn;
369 irq = bind_evtchn_to_irq(evtchn);
370 if (irq < 0)
371 return irq;
372 info->irq = irq;
373 devid = dev->nodename[strlen(dev->nodename) - 1] - '0';
374 info->hvc = hvc_alloc(xenbus_devid_to_vtermno(devid),
375 irq, &domU_hvc_ops, 256);
376 if (IS_ERR(info->hvc))
377 return PTR_ERR(info->hvc);
378 if (xen_pv_domain())
379 mfn = virt_to_mfn(info->intf);
380 else 180 else
381 mfn = __pa(info->intf) >> PAGE_SHIFT; 181 irq_set_noprobe(xencons_irq);
382 ret = gnttab_alloc_grant_references(1, &gref_head);
383 if (ret < 0)
384 return ret;
385 info->gntref = gref_head;
386 ref = gnttab_claim_grant_reference(&gref_head);
387 if (ref < 0)
388 return ref;
389 gnttab_grant_foreign_access_ref(ref, info->xbdev->otherend_id,
390 mfn, 0);
391
392 again:
393 ret = xenbus_transaction_start(&xbt);
394 if (ret) {
395 xenbus_dev_fatal(dev, ret, "starting transaction");
396 return ret;
397 }
398 ret = xenbus_printf(xbt, dev->nodename, "ring-ref", "%d", ref);
399 if (ret)
400 goto error_xenbus;
401 ret = xenbus_printf(xbt, dev->nodename, "port", "%u",
402 evtchn);
403 if (ret)
404 goto error_xenbus;
405 ret = xenbus_printf(xbt, dev->nodename, "type", "ioemu");
406 if (ret)
407 goto error_xenbus;
408 ret = xenbus_transaction_end(xbt, 0);
409 if (ret) {
410 if (ret == -EAGAIN)
411 goto again;
412 xenbus_dev_fatal(dev, ret, "completing transaction");
413 return ret;
414 }
415 182
416 xenbus_switch_state(dev, XenbusStateInitialised); 183 hp = hvc_alloc(HVC_COOKIE, xencons_irq, ops, 256);
417 return 0; 184 if (IS_ERR(hp))
185 return PTR_ERR(hp);
418 186
419 error_xenbus: 187 hvc = hp;
420 xenbus_transaction_end(xbt, 1);
421 xenbus_dev_fatal(dev, ret, "writing xenstore");
422 return ret;
423}
424 188
425static int xencons_probe(struct xenbus_device *dev, 189 console_pfn = mfn_to_pfn(xen_start_info->console.domU.mfn);
426 const struct xenbus_device_id *id)
427{
428 int ret, devid;
429 struct xencons_info *info;
430
431 devid = dev->nodename[strlen(dev->nodename) - 1] - '0';
432 if (devid == 0)
433 return -ENODEV;
434
435 info = kzalloc(sizeof(struct xencons_info), GFP_KERNEL);
436 if (!info)
437 return -ENOMEM;
438 dev_set_drvdata(&dev->dev, info);
439 info->xbdev = dev;
440 info->vtermno = xenbus_devid_to_vtermno(devid);
441 info->intf = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
442 if (!info->intf)
443 goto error_nomem;
444
445 ret = xencons_connect_backend(dev, info);
446 if (ret < 0)
447 goto error;
448 spin_lock(&xencons_lock);
449 list_add_tail(&info->list, &xenconsoles);
450 spin_unlock(&xencons_lock);
451 190
452 return 0; 191 return 0;
453
454 error_nomem:
455 ret = -ENOMEM;
456 xenbus_dev_fatal(dev, ret, "allocating device memory");
457 error:
458 xencons_disconnect_backend(info);
459 xencons_free(info);
460 return ret;
461}
462
463static int xencons_resume(struct xenbus_device *dev)
464{
465 struct xencons_info *info = dev_get_drvdata(&dev->dev);
466
467 xencons_disconnect_backend(info);
468 memset(info->intf, 0, PAGE_SIZE);
469 return xencons_connect_backend(dev, info);
470}
471
472static void xencons_backend_changed(struct xenbus_device *dev,
473 enum xenbus_state backend_state)
474{
475 switch (backend_state) {
476 case XenbusStateReconfiguring:
477 case XenbusStateReconfigured:
478 case XenbusStateInitialising:
479 case XenbusStateInitialised:
480 case XenbusStateUnknown:
481 break;
482
483 case XenbusStateInitWait:
484 break;
485
486 case XenbusStateConnected:
487 xenbus_switch_state(dev, XenbusStateConnected);
488 break;
489
490 case XenbusStateClosed:
491 if (dev->state == XenbusStateClosed)
492 break;
493 /* Missed the backend's CLOSING state -- fallthrough */
494 case XenbusStateClosing:
495 xenbus_frontend_closed(dev);
496 break;
497 }
498} 192}
499 193
500static const struct xenbus_device_id xencons_ids[] = { 194void xen_console_resume(void)
501 { "console" },
502 { "" }
503};
504
505
506static DEFINE_XENBUS_DRIVER(xencons, "xenconsole",
507 .probe = xencons_probe,
508 .remove = xencons_remove,
509 .resume = xencons_resume,
510 .otherend_changed = xencons_backend_changed,
511);
512#endif /* CONFIG_HVC_XEN_FRONTEND */
513
514static int __init xen_hvc_init(void)
515{ 195{
516 int r; 196 if (xencons_irq)
517 struct xencons_info *info; 197 rebind_evtchn_irq(xen_start_info->console.domU.evtchn, xencons_irq);
518 const struct hv_ops *ops;
519
520 if (!xen_domain())
521 return -ENODEV;
522
523 if (xen_initial_domain()) {
524 ops = &dom0_hvc_ops;
525 r = xen_initial_domain_console_init();
526 if (r < 0)
527 return r;
528 info = vtermno_to_xencons(HVC_COOKIE);
529 } else {
530 ops = &domU_hvc_ops;
531 if (xen_hvm_domain())
532 r = xen_hvm_console_init();
533 else
534 r = xen_pv_console_init();
535 if (r < 0)
536 return r;
537
538 info = vtermno_to_xencons(HVC_COOKIE);
539 info->irq = bind_evtchn_to_irq(info->evtchn);
540 }
541 if (info->irq < 0)
542 info->irq = 0; /* NO_IRQ */
543 else
544 irq_set_noprobe(info->irq);
545
546 info->hvc = hvc_alloc(HVC_COOKIE, info->irq, ops, 256);
547 if (IS_ERR(info->hvc)) {
548 r = PTR_ERR(info->hvc);
549 spin_lock(&xencons_lock);
550 list_del(&info->list);
551 spin_unlock(&xencons_lock);
552 if (info->irq)
553 unbind_from_irqhandler(info->irq, NULL);
554 kfree(info);
555 return r;
556 }
557
558 r = 0;
559#ifdef CONFIG_HVC_XEN_FRONTEND
560 r = xenbus_register_frontend(&xencons_driver);
561#endif
562 return r;
563} 198}
564 199
565static void __exit xen_hvc_fini(void) 200static void __exit xen_hvc_fini(void)
566{ 201{
567 struct xencons_info *entry, *next; 202 if (hvc)
568 203 hvc_remove(hvc);
569 if (list_empty(&xenconsoles))
570 return;
571
572 list_for_each_entry_safe(entry, next, &xenconsoles, list) {
573 xen_console_remove(entry);
574 }
575} 204}
576 205
577static int xen_cons_init(void) 206static int xen_cons_init(void)
578{ 207{
579 const struct hv_ops *ops; 208 struct hv_ops *ops;
580 209
581 if (!xen_domain()) 210 if (!xen_pv_domain())
582 return 0; 211 return 0;
583 212
584 if (xen_initial_domain()) 213 if (xen_initial_domain())
585 ops = &dom0_hvc_ops; 214 ops = &dom0_hvc_ops;
586 else { 215 else
587 int r;
588 ops = &domU_hvc_ops; 216 ops = &domU_hvc_ops;
589 217
590 if (xen_hvm_domain())
591 r = xen_hvm_console_init();
592 else
593 r = xen_pv_console_init();
594 if (r < 0)
595 return r;
596 }
597
598 hvc_instantiate(HVC_COOKIE, 0, ops); 218 hvc_instantiate(HVC_COOKIE, 0, ops);
599 return 0; 219 return 0;
600} 220}
601 221
602
603module_init(xen_hvc_init); 222module_init(xen_hvc_init);
604module_exit(xen_hvc_fini); 223module_exit(xen_hvc_fini);
605console_initcall(xen_cons_init); 224console_initcall(xen_cons_init);
@@ -611,9 +230,6 @@ static void xenboot_write_console(struct console *console, const char *string,
611 unsigned int linelen, off = 0; 230 unsigned int linelen, off = 0;
612 const char *pos; 231 const char *pos;
613 232
614 if (!xen_pv_domain())
615 return;
616
617 dom0_write_console(0, string, len); 233 dom0_write_console(0, string, len);
618 234
619 if (xen_initial_domain()) 235 if (xen_initial_domain())
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c
index 87763573395..4c8b6654693 100644
--- a/drivers/tty/hvc/hvcs.c
+++ b/drivers/tty/hvc/hvcs.c
@@ -261,7 +261,6 @@ static DEFINE_SPINLOCK(hvcs_pi_lock);
261 261
262/* One vty-server per hvcs_struct */ 262/* One vty-server per hvcs_struct */
263struct hvcs_struct { 263struct hvcs_struct {
264 struct tty_port port;
265 spinlock_t lock; 264 spinlock_t lock;
266 265
267 /* 266 /*
@@ -270,6 +269,9 @@ struct hvcs_struct {
270 */ 269 */
271 unsigned int index; 270 unsigned int index;
272 271
272 struct tty_struct *tty;
273 int open_count;
274
273 /* 275 /*
274 * Used to tell the driver kernel_thread what operations need to take 276 * Used to tell the driver kernel_thread what operations need to take
275 * place upon this hvcs_struct instance. 277 * place upon this hvcs_struct instance.
@@ -288,11 +290,12 @@ struct hvcs_struct {
288 int chars_in_buffer; 290 int chars_in_buffer;
289 291
290 /* 292 /*
291 * Any variable below is valid before a tty is connected and 293 * Any variable below the kref is valid before a tty is connected and
292 * stays valid after the tty is disconnected. These shouldn't be 294 * stays valid after the tty is disconnected. These shouldn't be
293 * whacked until the kobject refcount reaches zero though some entries 295 * whacked until the kobject refcount reaches zero though some entries
294 * may be changed via sysfs initiatives. 296 * may be changed via sysfs initiatives.
295 */ 297 */
298 struct kref kref; /* ref count & hvcs_struct lifetime */
296 int connected; /* is the vty-server currently connected to a vty? */ 299 int connected; /* is the vty-server currently connected to a vty? */
297 uint32_t p_unit_address; /* partner unit address */ 300 uint32_t p_unit_address; /* partner unit address */
298 uint32_t p_partition_ID; /* partner partition ID */ 301 uint32_t p_partition_ID; /* partner partition ID */
@@ -301,6 +304,9 @@ struct hvcs_struct {
301 struct vio_dev *vdev; 304 struct vio_dev *vdev;
302}; 305};
303 306
307/* Required to back map a kref to its containing object */
308#define from_kref(k) container_of(k, struct hvcs_struct, kref)
309
304static LIST_HEAD(hvcs_structs); 310static LIST_HEAD(hvcs_structs);
305static DEFINE_SPINLOCK(hvcs_structs_lock); 311static DEFINE_SPINLOCK(hvcs_structs_lock);
306static DEFINE_MUTEX(hvcs_init_mutex); 312static DEFINE_MUTEX(hvcs_init_mutex);
@@ -330,12 +336,12 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp);
330static void hvcs_close(struct tty_struct *tty, struct file *filp); 336static void hvcs_close(struct tty_struct *tty, struct file *filp);
331static void hvcs_hangup(struct tty_struct * tty); 337static void hvcs_hangup(struct tty_struct * tty);
332 338
333static int hvcs_probe(struct vio_dev *dev, 339static int __devinit hvcs_probe(struct vio_dev *dev,
334 const struct vio_device_id *id); 340 const struct vio_device_id *id);
335static int hvcs_remove(struct vio_dev *dev); 341static int __devexit hvcs_remove(struct vio_dev *dev);
336static int __init hvcs_module_init(void); 342static int __init hvcs_module_init(void);
337static void __exit hvcs_module_exit(void); 343static void __exit hvcs_module_exit(void);
338static int hvcs_initialize(void); 344static int __devinit hvcs_initialize(void);
339 345
340#define HVCS_SCHED_READ 0x00000001 346#define HVCS_SCHED_READ 0x00000001
341#define HVCS_QUICK_READ 0x00000002 347#define HVCS_QUICK_READ 0x00000002
@@ -416,7 +422,7 @@ static ssize_t hvcs_vterm_state_store(struct device *dev, struct device_attribut
416 422
417 spin_lock_irqsave(&hvcsd->lock, flags); 423 spin_lock_irqsave(&hvcsd->lock, flags);
418 424
419 if (hvcsd->port.count > 0) { 425 if (hvcsd->open_count > 0) {
420 spin_unlock_irqrestore(&hvcsd->lock, flags); 426 spin_unlock_irqrestore(&hvcsd->lock, flags);
421 printk(KERN_INFO "HVCS: vterm state unchanged. " 427 printk(KERN_INFO "HVCS: vterm state unchanged. "
422 "The hvcs device node is still in use.\n"); 428 "The hvcs device node is still in use.\n");
@@ -558,7 +564,7 @@ static irqreturn_t hvcs_handle_interrupt(int irq, void *dev_instance)
558static void hvcs_try_write(struct hvcs_struct *hvcsd) 564static void hvcs_try_write(struct hvcs_struct *hvcsd)
559{ 565{
560 uint32_t unit_address = hvcsd->vdev->unit_address; 566 uint32_t unit_address = hvcsd->vdev->unit_address;
561 struct tty_struct *tty = hvcsd->port.tty; 567 struct tty_struct *tty = hvcsd->tty;
562 int sent; 568 int sent;
563 569
564 if (hvcsd->todo_mask & HVCS_TRY_WRITE) { 570 if (hvcsd->todo_mask & HVCS_TRY_WRITE) {
@@ -596,7 +602,7 @@ static int hvcs_io(struct hvcs_struct *hvcsd)
596 spin_lock_irqsave(&hvcsd->lock, flags); 602 spin_lock_irqsave(&hvcsd->lock, flags);
597 603
598 unit_address = hvcsd->vdev->unit_address; 604 unit_address = hvcsd->vdev->unit_address;
599 tty = hvcsd->port.tty; 605 tty = hvcsd->tty;
600 606
601 hvcs_try_write(hvcsd); 607 hvcs_try_write(hvcsd);
602 608
@@ -676,7 +682,7 @@ static int khvcsd(void *unused)
676 return 0; 682 return 0;
677} 683}
678 684
679static struct vio_device_id hvcs_driver_table[] = { 685static struct vio_device_id hvcs_driver_table[] __devinitdata= {
680 {"serial-server", "hvterm2"}, 686 {"serial-server", "hvterm2"},
681 { "", "" } 687 { "", "" }
682}; 688};
@@ -695,9 +701,10 @@ static void hvcs_return_index(int index)
695 hvcs_index_list[index] = -1; 701 hvcs_index_list[index] = -1;
696} 702}
697 703
698static void hvcs_destruct_port(struct tty_port *p) 704/* callback when the kref ref count reaches zero */
705static void destroy_hvcs_struct(struct kref *kref)
699{ 706{
700 struct hvcs_struct *hvcsd = container_of(p, struct hvcs_struct, port); 707 struct hvcs_struct *hvcsd = from_kref(kref);
701 struct vio_dev *vdev; 708 struct vio_dev *vdev;
702 unsigned long flags; 709 unsigned long flags;
703 710
@@ -734,10 +741,6 @@ static void hvcs_destruct_port(struct tty_port *p)
734 kfree(hvcsd); 741 kfree(hvcsd);
735} 742}
736 743
737static const struct tty_port_operations hvcs_port_ops = {
738 .destruct = hvcs_destruct_port,
739};
740
741static int hvcs_get_index(void) 744static int hvcs_get_index(void)
742{ 745{
743 int i; 746 int i;
@@ -756,7 +759,7 @@ static int hvcs_get_index(void)
756 return -1; 759 return -1;
757} 760}
758 761
759static int hvcs_probe( 762static int __devinit hvcs_probe(
760 struct vio_dev *dev, 763 struct vio_dev *dev,
761 const struct vio_device_id *id) 764 const struct vio_device_id *id)
762{ 765{
@@ -786,9 +789,10 @@ static int hvcs_probe(
786 if (!hvcsd) 789 if (!hvcsd)
787 return -ENODEV; 790 return -ENODEV;
788 791
789 tty_port_init(&hvcsd->port); 792
790 hvcsd->port.ops = &hvcs_port_ops;
791 spin_lock_init(&hvcsd->lock); 793 spin_lock_init(&hvcsd->lock);
794 /* Automatically incs the refcount the first time */
795 kref_init(&hvcsd->kref);
792 796
793 hvcsd->vdev = dev; 797 hvcsd->vdev = dev;
794 dev_set_drvdata(&dev->dev, hvcsd); 798 dev_set_drvdata(&dev->dev, hvcsd);
@@ -835,7 +839,7 @@ static int hvcs_probe(
835 return 0; 839 return 0;
836} 840}
837 841
838static int hvcs_remove(struct vio_dev *dev) 842static int __devexit hvcs_remove(struct vio_dev *dev)
839{ 843{
840 struct hvcs_struct *hvcsd = dev_get_drvdata(&dev->dev); 844 struct hvcs_struct *hvcsd = dev_get_drvdata(&dev->dev);
841 unsigned long flags; 845 unsigned long flags;
@@ -848,7 +852,7 @@ static int hvcs_remove(struct vio_dev *dev)
848 852
849 spin_lock_irqsave(&hvcsd->lock, flags); 853 spin_lock_irqsave(&hvcsd->lock, flags);
850 854
851 tty = hvcsd->port.tty; 855 tty = hvcsd->tty;
852 856
853 spin_unlock_irqrestore(&hvcsd->lock, flags); 857 spin_unlock_irqrestore(&hvcsd->lock, flags);
854 858
@@ -856,7 +860,7 @@ static int hvcs_remove(struct vio_dev *dev)
856 * Let the last holder of this object cause it to be removed, which 860 * Let the last holder of this object cause it to be removed, which
857 * would probably be tty_hangup below. 861 * would probably be tty_hangup below.
858 */ 862 */
859 tty_port_put(&hvcsd->port); 863 kref_put(&hvcsd->kref, destroy_hvcs_struct);
860 864
861 /* 865 /*
862 * The hangup is a scheduled function which will auto chain call 866 * The hangup is a scheduled function which will auto chain call
@@ -874,8 +878,11 @@ static int hvcs_remove(struct vio_dev *dev)
874static struct vio_driver hvcs_vio_driver = { 878static struct vio_driver hvcs_vio_driver = {
875 .id_table = hvcs_driver_table, 879 .id_table = hvcs_driver_table,
876 .probe = hvcs_probe, 880 .probe = hvcs_probe,
877 .remove = hvcs_remove, 881 .remove = __devexit_p(hvcs_remove),
878 .name = hvcs_driver_name, 882 .driver = {
883 .name = hvcs_driver_name,
884 .owner = THIS_MODULE,
885 }
879}; 886};
880 887
881/* Only called from hvcs_get_pi please */ 888/* Only called from hvcs_get_pi please */
@@ -1050,7 +1057,7 @@ static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address,
1050 * the conn was registered and now. 1057 * the conn was registered and now.
1051 */ 1058 */
1052 if (!(rc = request_irq(irq, &hvcs_handle_interrupt, 1059 if (!(rc = request_irq(irq, &hvcs_handle_interrupt,
1053 0, "ibmhvcs", hvcsd))) { 1060 IRQF_DISABLED, "ibmhvcs", hvcsd))) {
1054 /* 1061 /*
1055 * It is possible the vty-server was removed after the irq was 1062 * It is possible the vty-server was removed after the irq was
1056 * requested but before we have time to enable interrupts. 1063 * requested but before we have time to enable interrupts.
@@ -1083,39 +1090,50 @@ static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address,
1083 */ 1090 */
1084static struct hvcs_struct *hvcs_get_by_index(int index) 1091static struct hvcs_struct *hvcs_get_by_index(int index)
1085{ 1092{
1086 struct hvcs_struct *hvcsd; 1093 struct hvcs_struct *hvcsd = NULL;
1087 unsigned long flags; 1094 unsigned long flags;
1088 1095
1089 spin_lock(&hvcs_structs_lock); 1096 spin_lock(&hvcs_structs_lock);
1090 list_for_each_entry(hvcsd, &hvcs_structs, next) { 1097 /* We can immediately discard OOB requests */
1091 spin_lock_irqsave(&hvcsd->lock, flags); 1098 if (index >= 0 && index < HVCS_MAX_SERVER_ADAPTERS) {
1092 if (hvcsd->index == index) { 1099 list_for_each_entry(hvcsd, &hvcs_structs, next) {
1093 tty_port_get(&hvcsd->port); 1100 spin_lock_irqsave(&hvcsd->lock, flags);
1101 if (hvcsd->index == index) {
1102 kref_get(&hvcsd->kref);
1103 spin_unlock_irqrestore(&hvcsd->lock, flags);
1104 spin_unlock(&hvcs_structs_lock);
1105 return hvcsd;
1106 }
1094 spin_unlock_irqrestore(&hvcsd->lock, flags); 1107 spin_unlock_irqrestore(&hvcsd->lock, flags);
1095 spin_unlock(&hvcs_structs_lock);
1096 return hvcsd;
1097 } 1108 }
1098 spin_unlock_irqrestore(&hvcsd->lock, flags); 1109 hvcsd = NULL;
1099 } 1110 }
1100 spin_unlock(&hvcs_structs_lock);
1101 1111
1102 return NULL; 1112 spin_unlock(&hvcs_structs_lock);
1113 return hvcsd;
1103} 1114}
1104 1115
1105static int hvcs_install(struct tty_driver *driver, struct tty_struct *tty) 1116/*
1117 * This is invoked via the tty_open interface when a user app connects to the
1118 * /dev node.
1119 */
1120static int hvcs_open(struct tty_struct *tty, struct file *filp)
1106{ 1121{
1107 struct hvcs_struct *hvcsd; 1122 struct hvcs_struct *hvcsd;
1108 struct vio_dev *vdev; 1123 int rc, retval = 0;
1109 unsigned long unit_address, flags; 1124 unsigned long flags;
1110 unsigned int irq; 1125 unsigned int irq;
1111 int retval; 1126 struct vio_dev *vdev;
1127 unsigned long unit_address;
1128
1129 if (tty->driver_data)
1130 goto fast_open;
1112 1131
1113 /* 1132 /*
1114 * Is there a vty-server that shares the same index? 1133 * Is there a vty-server that shares the same index?
1115 * This function increments the kref index. 1134 * This function increments the kref index.
1116 */ 1135 */
1117 hvcsd = hvcs_get_by_index(tty->index); 1136 if (!(hvcsd = hvcs_get_by_index(tty->index))) {
1118 if (!hvcsd) {
1119 printk(KERN_WARNING "HVCS: open failed, no device associated" 1137 printk(KERN_WARNING "HVCS: open failed, no device associated"
1120 " with tty->index %d.\n", tty->index); 1138 " with tty->index %d.\n", tty->index);
1121 return -ENODEV; 1139 return -ENODEV;
@@ -1123,17 +1141,12 @@ static int hvcs_install(struct tty_driver *driver, struct tty_struct *tty)
1123 1141
1124 spin_lock_irqsave(&hvcsd->lock, flags); 1142 spin_lock_irqsave(&hvcsd->lock, flags);
1125 1143
1126 if (hvcsd->connected == 0) { 1144 if (hvcsd->connected == 0)
1127 retval = hvcs_partner_connect(hvcsd); 1145 if ((retval = hvcs_partner_connect(hvcsd)))
1128 if (retval) { 1146 goto error_release;
1129 spin_unlock_irqrestore(&hvcsd->lock, flags);
1130 printk(KERN_WARNING "HVCS: partner connect failed.\n");
1131 goto err_put;
1132 }
1133 }
1134 1147
1135 hvcsd->port.count = 0; 1148 hvcsd->open_count = 1;
1136 hvcsd->port.tty = tty; 1149 hvcsd->tty = tty;
1137 tty->driver_data = hvcsd; 1150 tty->driver_data = hvcsd;
1138 1151
1139 memset(&hvcsd->buffer[0], 0x00, HVCS_BUFF_LEN); 1152 memset(&hvcsd->buffer[0], 0x00, HVCS_BUFF_LEN);
@@ -1153,55 +1166,44 @@ static int hvcs_install(struct tty_driver *driver, struct tty_struct *tty)
1153 * This must be done outside of the spinlock because it requests irqs 1166 * This must be done outside of the spinlock because it requests irqs
1154 * and will grab the spinlock and free the connection if it fails. 1167 * and will grab the spinlock and free the connection if it fails.
1155 */ 1168 */
1156 retval = hvcs_enable_device(hvcsd, unit_address, irq, vdev); 1169 if (((rc = hvcs_enable_device(hvcsd, unit_address, irq, vdev)))) {
1157 if (retval) { 1170 kref_put(&hvcsd->kref, destroy_hvcs_struct);
1158 printk(KERN_WARNING "HVCS: enable device failed.\n"); 1171 printk(KERN_WARNING "HVCS: enable device failed.\n");
1159 goto err_put; 1172 return rc;
1160 } 1173 }
1161 1174
1162 retval = tty_port_install(&hvcsd->port, driver, tty); 1175 goto open_success;
1163 if (retval)
1164 goto err_irq;
1165 1176
1166 return 0; 1177fast_open:
1167err_irq: 1178 hvcsd = tty->driver_data;
1168 spin_lock_irqsave(&hvcsd->lock, flags);
1169 vio_disable_interrupts(hvcsd->vdev);
1170 spin_unlock_irqrestore(&hvcsd->lock, flags);
1171 free_irq(irq, hvcsd);
1172err_put:
1173 tty_port_put(&hvcsd->port);
1174
1175 return retval;
1176}
1177
1178/*
1179 * This is invoked via the tty_open interface when a user app connects to the
1180 * /dev node.
1181 */
1182static int hvcs_open(struct tty_struct *tty, struct file *filp)
1183{
1184 struct hvcs_struct *hvcsd = tty->driver_data;
1185 unsigned long flags;
1186 1179
1187 spin_lock_irqsave(&hvcsd->lock, flags); 1180 spin_lock_irqsave(&hvcsd->lock, flags);
1188 hvcsd->port.count++; 1181 kref_get(&hvcsd->kref);
1182 hvcsd->open_count++;
1189 hvcsd->todo_mask |= HVCS_SCHED_READ; 1183 hvcsd->todo_mask |= HVCS_SCHED_READ;
1190 spin_unlock_irqrestore(&hvcsd->lock, flags); 1184 spin_unlock_irqrestore(&hvcsd->lock, flags);
1191 1185
1186open_success:
1192 hvcs_kick(); 1187 hvcs_kick();
1193 1188
1194 printk(KERN_INFO "HVCS: vty-server@%X connection opened.\n", 1189 printk(KERN_INFO "HVCS: vty-server@%X connection opened.\n",
1195 hvcsd->vdev->unit_address ); 1190 hvcsd->vdev->unit_address );
1196 1191
1197 return 0; 1192 return 0;
1193
1194error_release:
1195 spin_unlock_irqrestore(&hvcsd->lock, flags);
1196 kref_put(&hvcsd->kref, destroy_hvcs_struct);
1197
1198 printk(KERN_WARNING "HVCS: partner connect failed.\n");
1199 return retval;
1198} 1200}
1199 1201
1200static void hvcs_close(struct tty_struct *tty, struct file *filp) 1202static void hvcs_close(struct tty_struct *tty, struct file *filp)
1201{ 1203{
1202 struct hvcs_struct *hvcsd; 1204 struct hvcs_struct *hvcsd;
1203 unsigned long flags; 1205 unsigned long flags;
1204 int irq; 1206 int irq = NO_IRQ;
1205 1207
1206 /* 1208 /*
1207 * Is someone trying to close the file associated with this device after 1209 * Is someone trying to close the file associated with this device after
@@ -1221,7 +1223,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
1221 hvcsd = tty->driver_data; 1223 hvcsd = tty->driver_data;
1222 1224
1223 spin_lock_irqsave(&hvcsd->lock, flags); 1225 spin_lock_irqsave(&hvcsd->lock, flags);
1224 if (--hvcsd->port.count == 0) { 1226 if (--hvcsd->open_count == 0) {
1225 1227
1226 vio_disable_interrupts(hvcsd->vdev); 1228 vio_disable_interrupts(hvcsd->vdev);
1227 1229
@@ -1230,12 +1232,12 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
1230 * execute any operations on the TTY even though it is obligated 1232 * execute any operations on the TTY even though it is obligated
1231 * to deliver any pending I/O to the hypervisor. 1233 * to deliver any pending I/O to the hypervisor.
1232 */ 1234 */
1233 hvcsd->port.tty = NULL; 1235 hvcsd->tty = NULL;
1234 1236
1235 irq = hvcsd->vdev->irq; 1237 irq = hvcsd->vdev->irq;
1236 spin_unlock_irqrestore(&hvcsd->lock, flags); 1238 spin_unlock_irqrestore(&hvcsd->lock, flags);
1237 1239
1238 tty_wait_until_sent_from_close(tty, HVCS_CLOSE_WAIT); 1240 tty_wait_until_sent(tty, HVCS_CLOSE_WAIT);
1239 1241
1240 /* 1242 /*
1241 * This line is important because it tells hvcs_open that this 1243 * This line is important because it tells hvcs_open that this
@@ -1245,21 +1247,16 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp)
1245 tty->driver_data = NULL; 1247 tty->driver_data = NULL;
1246 1248
1247 free_irq(irq, hvcsd); 1249 free_irq(irq, hvcsd);
1250 kref_put(&hvcsd->kref, destroy_hvcs_struct);
1248 return; 1251 return;
1249 } else if (hvcsd->port.count < 0) { 1252 } else if (hvcsd->open_count < 0) {
1250 printk(KERN_ERR "HVCS: vty-server@%X open_count: %d" 1253 printk(KERN_ERR "HVCS: vty-server@%X open_count: %d"
1251 " is missmanaged.\n", 1254 " is missmanaged.\n",
1252 hvcsd->vdev->unit_address, hvcsd->port.count); 1255 hvcsd->vdev->unit_address, hvcsd->open_count);
1253 } 1256 }
1254 1257
1255 spin_unlock_irqrestore(&hvcsd->lock, flags); 1258 spin_unlock_irqrestore(&hvcsd->lock, flags);
1256} 1259 kref_put(&hvcsd->kref, destroy_hvcs_struct);
1257
1258static void hvcs_cleanup(struct tty_struct * tty)
1259{
1260 struct hvcs_struct *hvcsd = tty->driver_data;
1261
1262 tty_port_put(&hvcsd->port);
1263} 1260}
1264 1261
1265static void hvcs_hangup(struct tty_struct * tty) 1262static void hvcs_hangup(struct tty_struct * tty)
@@ -1267,11 +1264,11 @@ static void hvcs_hangup(struct tty_struct * tty)
1267 struct hvcs_struct *hvcsd = tty->driver_data; 1264 struct hvcs_struct *hvcsd = tty->driver_data;
1268 unsigned long flags; 1265 unsigned long flags;
1269 int temp_open_count; 1266 int temp_open_count;
1270 int irq; 1267 int irq = NO_IRQ;
1271 1268
1272 spin_lock_irqsave(&hvcsd->lock, flags); 1269 spin_lock_irqsave(&hvcsd->lock, flags);
1273 /* Preserve this so that we know how many kref refs to put */ 1270 /* Preserve this so that we know how many kref refs to put */
1274 temp_open_count = hvcsd->port.count; 1271 temp_open_count = hvcsd->open_count;
1275 1272
1276 /* 1273 /*
1277 * Don't kref put inside the spinlock because the destruction 1274 * Don't kref put inside the spinlock because the destruction
@@ -1283,10 +1280,10 @@ static void hvcs_hangup(struct tty_struct * tty)
1283 hvcsd->todo_mask = 0; 1280 hvcsd->todo_mask = 0;
1284 1281
1285 /* I don't think the tty needs the hvcs_struct pointer after a hangup */ 1282 /* I don't think the tty needs the hvcs_struct pointer after a hangup */
1286 tty->driver_data = NULL; 1283 hvcsd->tty->driver_data = NULL;
1287 hvcsd->port.tty = NULL; 1284 hvcsd->tty = NULL;
1288 1285
1289 hvcsd->port.count = 0; 1286 hvcsd->open_count = 0;
1290 1287
1291 /* This will drop any buffered data on the floor which is OK in a hangup 1288 /* This will drop any buffered data on the floor which is OK in a hangup
1292 * scenario. */ 1289 * scenario. */
@@ -1311,7 +1308,7 @@ static void hvcs_hangup(struct tty_struct * tty)
1311 * NOTE: If this hangup was signaled from user space then the 1308 * NOTE: If this hangup was signaled from user space then the
1312 * final put will never happen. 1309 * final put will never happen.
1313 */ 1310 */
1314 tty_port_put(&hvcsd->port); 1311 kref_put(&hvcsd->kref, destroy_hvcs_struct);
1315 } 1312 }
1316} 1313}
1317 1314
@@ -1357,7 +1354,7 @@ static int hvcs_write(struct tty_struct *tty,
1357 * the middle of a write operation? This is a crummy place to do this 1354 * the middle of a write operation? This is a crummy place to do this
1358 * but we want to keep it all in the spinlock. 1355 * but we want to keep it all in the spinlock.
1359 */ 1356 */
1360 if (hvcsd->port.count <= 0) { 1357 if (hvcsd->open_count <= 0) {
1361 spin_unlock_irqrestore(&hvcsd->lock, flags); 1358 spin_unlock_irqrestore(&hvcsd->lock, flags);
1362 return -ENODEV; 1359 return -ENODEV;
1363 } 1360 }
@@ -1431,7 +1428,7 @@ static int hvcs_write_room(struct tty_struct *tty)
1431{ 1428{
1432 struct hvcs_struct *hvcsd = tty->driver_data; 1429 struct hvcs_struct *hvcsd = tty->driver_data;
1433 1430
1434 if (!hvcsd || hvcsd->port.count <= 0) 1431 if (!hvcsd || hvcsd->open_count <= 0)
1435 return 0; 1432 return 0;
1436 1433
1437 return HVCS_BUFF_LEN - hvcsd->chars_in_buffer; 1434 return HVCS_BUFF_LEN - hvcsd->chars_in_buffer;
@@ -1445,10 +1442,8 @@ static int hvcs_chars_in_buffer(struct tty_struct *tty)
1445} 1442}
1446 1443
1447static const struct tty_operations hvcs_ops = { 1444static const struct tty_operations hvcs_ops = {
1448 .install = hvcs_install,
1449 .open = hvcs_open, 1445 .open = hvcs_open,
1450 .close = hvcs_close, 1446 .close = hvcs_close,
1451 .cleanup = hvcs_cleanup,
1452 .hangup = hvcs_hangup, 1447 .hangup = hvcs_hangup,
1453 .write = hvcs_write, 1448 .write = hvcs_write,
1454 .write_room = hvcs_write_room, 1449 .write_room = hvcs_write_room,
@@ -1478,7 +1473,7 @@ static void hvcs_free_index_list(void)
1478 hvcs_index_count = 0; 1473 hvcs_index_count = 0;
1479} 1474}
1480 1475
1481static int hvcs_initialize(void) 1476static int __devinit hvcs_initialize(void)
1482{ 1477{
1483 int rc, num_ttys_to_alloc; 1478 int rc, num_ttys_to_alloc;
1484 1479
@@ -1496,16 +1491,16 @@ static int hvcs_initialize(void)
1496 num_ttys_to_alloc = hvcs_parm_num_devs; 1491 num_ttys_to_alloc = hvcs_parm_num_devs;
1497 1492
1498 hvcs_tty_driver = alloc_tty_driver(num_ttys_to_alloc); 1493 hvcs_tty_driver = alloc_tty_driver(num_ttys_to_alloc);
1499 if (!hvcs_tty_driver) { 1494 if (!hvcs_tty_driver)
1500 mutex_unlock(&hvcs_init_mutex);
1501 return -ENOMEM; 1495 return -ENOMEM;
1502 }
1503 1496
1504 if (hvcs_alloc_index_list(num_ttys_to_alloc)) { 1497 if (hvcs_alloc_index_list(num_ttys_to_alloc)) {
1505 rc = -ENOMEM; 1498 rc = -ENOMEM;
1506 goto index_fail; 1499 goto index_fail;
1507 } 1500 }
1508 1501
1502 hvcs_tty_driver->owner = THIS_MODULE;
1503
1509 hvcs_tty_driver->driver_name = hvcs_driver_name; 1504 hvcs_tty_driver->driver_name = hvcs_driver_name;
1510 hvcs_tty_driver->name = hvcs_device_node; 1505 hvcs_tty_driver->name = hvcs_device_node;
1511 1506
@@ -1537,7 +1532,7 @@ static int hvcs_initialize(void)
1537 goto register_fail; 1532 goto register_fail;
1538 } 1533 }
1539 1534
1540 hvcs_pi_buff = (unsigned long *) __get_free_page(GFP_KERNEL); 1535 hvcs_pi_buff = kmalloc(PAGE_SIZE, GFP_KERNEL);
1541 if (!hvcs_pi_buff) { 1536 if (!hvcs_pi_buff) {
1542 rc = -ENOMEM; 1537 rc = -ENOMEM;
1543 goto buff_alloc_fail; 1538 goto buff_alloc_fail;
@@ -1553,7 +1548,7 @@ static int hvcs_initialize(void)
1553 return 0; 1548 return 0;
1554 1549
1555kthread_fail: 1550kthread_fail:
1556 free_page((unsigned long)hvcs_pi_buff); 1551 kfree(hvcs_pi_buff);
1557buff_alloc_fail: 1552buff_alloc_fail:
1558 tty_unregister_driver(hvcs_tty_driver); 1553 tty_unregister_driver(hvcs_tty_driver);
1559register_fail: 1554register_fail:
@@ -1602,7 +1597,7 @@ static void __exit hvcs_module_exit(void)
1602 kthread_stop(hvcs_task); 1597 kthread_stop(hvcs_task);
1603 1598
1604 spin_lock(&hvcs_pi_lock); 1599 spin_lock(&hvcs_pi_lock);
1605 free_page((unsigned long)hvcs_pi_buff); 1600 kfree(hvcs_pi_buff);
1606 hvcs_pi_buff = NULL; 1601 hvcs_pi_buff = NULL;
1607 spin_unlock(&hvcs_pi_lock); 1602 spin_unlock(&hvcs_pi_lock);
1608 1603
diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c
index 68357a6e4de..c94e2f5853d 100644
--- a/drivers/tty/hvc/hvsi.c
+++ b/drivers/tty/hvc/hvsi.c
@@ -69,13 +69,14 @@
69#define __ALIGNED__ __attribute__((__aligned__(sizeof(long)))) 69#define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
70 70
71struct hvsi_struct { 71struct hvsi_struct {
72 struct tty_port port;
73 struct delayed_work writer; 72 struct delayed_work writer;
74 struct work_struct handshaker; 73 struct work_struct handshaker;
75 wait_queue_head_t emptyq; /* woken when outbuf is emptied */ 74 wait_queue_head_t emptyq; /* woken when outbuf is emptied */
76 wait_queue_head_t stateq; /* woken when HVSI state changes */ 75 wait_queue_head_t stateq; /* woken when HVSI state changes */
77 spinlock_t lock; 76 spinlock_t lock;
78 int index; 77 int index;
78 struct tty_struct *tty;
79 int count;
79 uint8_t throttle_buf[128]; 80 uint8_t throttle_buf[128];
80 uint8_t outbuf[N_OUTBUF]; /* to implement write_room and chars_in_buffer */ 81 uint8_t outbuf[N_OUTBUF]; /* to implement write_room and chars_in_buffer */
81 /* inbuf is for packet reassembly. leave a little room for leftovers. */ 82 /* inbuf is for packet reassembly. leave a little room for leftovers. */
@@ -236,7 +237,7 @@ static int hvsi_read(struct hvsi_struct *hp, char *buf, int count)
236} 237}
237 238
238static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet, 239static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
239 struct tty_struct *tty, struct hvsi_struct **to_handshake) 240 struct tty_struct **to_hangup, struct hvsi_struct **to_handshake)
240{ 241{
241 struct hvsi_control *header = (struct hvsi_control *)packet; 242 struct hvsi_control *header = (struct hvsi_control *)packet;
242 243
@@ -246,8 +247,9 @@ static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet,
246 /* CD went away; no more connection */ 247 /* CD went away; no more connection */
247 pr_debug("hvsi%i: CD dropped\n", hp->index); 248 pr_debug("hvsi%i: CD dropped\n", hp->index);
248 hp->mctrl &= TIOCM_CD; 249 hp->mctrl &= TIOCM_CD;
249 if (tty && !C_CLOCAL(tty)) 250 /* If userland hasn't done an open(2) yet, hp->tty is NULL. */
250 tty_hangup(tty); 251 if (hp->tty && !(hp->tty->flags & CLOCAL))
252 *to_hangup = hp->tty;
251 } 253 }
252 break; 254 break;
253 case VSV_CLOSE_PROTOCOL: 255 case VSV_CLOSE_PROTOCOL:
@@ -329,8 +331,7 @@ static void hvsi_recv_query(struct hvsi_struct *hp, uint8_t *packet)
329 } 331 }
330} 332}
331 333
332static void hvsi_insert_chars(struct hvsi_struct *hp, struct tty_struct *tty, 334static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len)
333 const char *buf, int len)
334{ 335{
335 int i; 336 int i;
336 337
@@ -346,7 +347,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, struct tty_struct *tty,
346 continue; 347 continue;
347 } 348 }
348#endif /* CONFIG_MAGIC_SYSRQ */ 349#endif /* CONFIG_MAGIC_SYSRQ */
349 tty_insert_flip_char(tty, c, 0); 350 tty_insert_flip_char(hp->tty, c, 0);
350 } 351 }
351} 352}
352 353
@@ -359,7 +360,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, struct tty_struct *tty,
359 * revisited. 360 * revisited.
360 */ 361 */
361#define TTY_THRESHOLD_THROTTLE 128 362#define TTY_THRESHOLD_THROTTLE 128
362static bool hvsi_recv_data(struct hvsi_struct *hp, struct tty_struct *tty, 363static struct tty_struct *hvsi_recv_data(struct hvsi_struct *hp,
363 const uint8_t *packet) 364 const uint8_t *packet)
364{ 365{
365 const struct hvsi_header *header = (const struct hvsi_header *)packet; 366 const struct hvsi_header *header = (const struct hvsi_header *)packet;
@@ -370,14 +371,14 @@ static bool hvsi_recv_data(struct hvsi_struct *hp, struct tty_struct *tty,
370 pr_debug("queueing %i chars '%.*s'\n", datalen, datalen, data); 371 pr_debug("queueing %i chars '%.*s'\n", datalen, datalen, data);
371 372
372 if (datalen == 0) 373 if (datalen == 0)
373 return false; 374 return NULL;
374 375
375 if (overflow > 0) { 376 if (overflow > 0) {
376 pr_debug("%s: got >TTY_THRESHOLD_THROTTLE bytes\n", __func__); 377 pr_debug("%s: got >TTY_THRESHOLD_THROTTLE bytes\n", __func__);
377 datalen = TTY_THRESHOLD_THROTTLE; 378 datalen = TTY_THRESHOLD_THROTTLE;
378 } 379 }
379 380
380 hvsi_insert_chars(hp, tty, data, datalen); 381 hvsi_insert_chars(hp, data, datalen);
381 382
382 if (overflow > 0) { 383 if (overflow > 0) {
383 /* 384 /*
@@ -389,7 +390,7 @@ static bool hvsi_recv_data(struct hvsi_struct *hp, struct tty_struct *tty,
389 hp->n_throttle = overflow; 390 hp->n_throttle = overflow;
390 } 391 }
391 392
392 return true; 393 return hp->tty;
393} 394}
394 395
395/* 396/*
@@ -398,13 +399,14 @@ static bool hvsi_recv_data(struct hvsi_struct *hp, struct tty_struct *tty,
398 * machine during console handshaking (in which case tty = NULL and we ignore 399 * machine during console handshaking (in which case tty = NULL and we ignore
399 * incoming data). 400 * incoming data).
400 */ 401 */
401static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct *tty, 402static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct **flip,
402 struct hvsi_struct **handshake) 403 struct tty_struct **hangup, struct hvsi_struct **handshake)
403{ 404{
404 uint8_t *packet = hp->inbuf; 405 uint8_t *packet = hp->inbuf;
405 int chunklen; 406 int chunklen;
406 bool flip = false;
407 407
408 *flip = NULL;
409 *hangup = NULL;
408 *handshake = NULL; 410 *handshake = NULL;
409 411
410 chunklen = hvsi_read(hp, hp->inbuf_end, HVSI_MAX_READ); 412 chunklen = hvsi_read(hp, hp->inbuf_end, HVSI_MAX_READ);
@@ -438,12 +440,12 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct *tty,
438 case VS_DATA_PACKET_HEADER: 440 case VS_DATA_PACKET_HEADER:
439 if (!is_open(hp)) 441 if (!is_open(hp))
440 break; 442 break;
441 if (tty == NULL) 443 if (hp->tty == NULL)
442 break; /* no tty buffer to put data in */ 444 break; /* no tty buffer to put data in */
443 flip = hvsi_recv_data(hp, tty, packet); 445 *flip = hvsi_recv_data(hp, packet);
444 break; 446 break;
445 case VS_CONTROL_PACKET_HEADER: 447 case VS_CONTROL_PACKET_HEADER:
446 hvsi_recv_control(hp, packet, tty, handshake); 448 hvsi_recv_control(hp, packet, hangup, handshake);
447 break; 449 break;
448 case VS_QUERY_RESPONSE_PACKET_HEADER: 450 case VS_QUERY_RESPONSE_PACKET_HEADER:
449 hvsi_recv_response(hp, packet); 451 hvsi_recv_response(hp, packet);
@@ -460,26 +462,28 @@ static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct *tty,
460 462
461 packet += len_packet(packet); 463 packet += len_packet(packet);
462 464
463 if (*handshake) { 465 if (*hangup || *handshake) {
464 pr_debug("%s: handshake\n", __func__); 466 pr_debug("%s: hangup or handshake\n", __func__);
467 /*
468 * we need to send the hangup now before receiving any more data.
469 * If we get "data, hangup, data", we can't deliver the second
470 * data before the hangup.
471 */
465 break; 472 break;
466 } 473 }
467 } 474 }
468 475
469 compact_inbuf(hp, packet); 476 compact_inbuf(hp, packet);
470 477
471 if (flip)
472 tty_flip_buffer_push(tty);
473
474 return 1; 478 return 1;
475} 479}
476 480
477static void hvsi_send_overflow(struct hvsi_struct *hp, struct tty_struct *tty) 481static void hvsi_send_overflow(struct hvsi_struct *hp)
478{ 482{
479 pr_debug("%s: delivering %i bytes overflow\n", __func__, 483 pr_debug("%s: delivering %i bytes overflow\n", __func__,
480 hp->n_throttle); 484 hp->n_throttle);
481 485
482 hvsi_insert_chars(hp, tty, hp->throttle_buf, hp->n_throttle); 486 hvsi_insert_chars(hp, hp->throttle_buf, hp->n_throttle);
483 hp->n_throttle = 0; 487 hp->n_throttle = 0;
484} 488}
485 489
@@ -490,20 +494,35 @@ static void hvsi_send_overflow(struct hvsi_struct *hp, struct tty_struct *tty)
490static irqreturn_t hvsi_interrupt(int irq, void *arg) 494static irqreturn_t hvsi_interrupt(int irq, void *arg)
491{ 495{
492 struct hvsi_struct *hp = (struct hvsi_struct *)arg; 496 struct hvsi_struct *hp = (struct hvsi_struct *)arg;
497 struct tty_struct *flip;
498 struct tty_struct *hangup;
493 struct hvsi_struct *handshake; 499 struct hvsi_struct *handshake;
494 struct tty_struct *tty;
495 unsigned long flags; 500 unsigned long flags;
496 int again = 1; 501 int again = 1;
497 502
498 pr_debug("%s\n", __func__); 503 pr_debug("%s\n", __func__);
499 504
500 tty = tty_port_tty_get(&hp->port);
501
502 while (again) { 505 while (again) {
503 spin_lock_irqsave(&hp->lock, flags); 506 spin_lock_irqsave(&hp->lock, flags);
504 again = hvsi_load_chunk(hp, tty, &handshake); 507 again = hvsi_load_chunk(hp, &flip, &hangup, &handshake);
505 spin_unlock_irqrestore(&hp->lock, flags); 508 spin_unlock_irqrestore(&hp->lock, flags);
506 509
510 /*
511 * we have to call tty_flip_buffer_push() and tty_hangup() outside our
512 * spinlock. But we also have to keep going until we've read all the
513 * available data.
514 */
515
516 if (flip) {
517 /* there was data put in the tty flip buffer */
518 tty_flip_buffer_push(flip);
519 flip = NULL;
520 }
521
522 if (hangup) {
523 tty_hangup(hangup);
524 }
525
507 if (handshake) { 526 if (handshake) {
508 pr_debug("hvsi%i: attempting re-handshake\n", handshake->index); 527 pr_debug("hvsi%i: attempting re-handshake\n", handshake->index);
509 schedule_work(&handshake->handshaker); 528 schedule_work(&handshake->handshaker);
@@ -511,15 +530,18 @@ static irqreturn_t hvsi_interrupt(int irq, void *arg)
511 } 530 }
512 531
513 spin_lock_irqsave(&hp->lock, flags); 532 spin_lock_irqsave(&hp->lock, flags);
514 if (tty && hp->n_throttle && !test_bit(TTY_THROTTLED, &tty->flags)) { 533 if (hp->tty && hp->n_throttle
515 /* we weren't hung up and we weren't throttled, so we can 534 && (!test_bit(TTY_THROTTLED, &hp->tty->flags))) {
516 * deliver the rest now */ 535 /* we weren't hung up and we weren't throttled, so we can deliver the
517 hvsi_send_overflow(hp, tty); 536 * rest now */
518 tty_flip_buffer_push(tty); 537 flip = hp->tty;
538 hvsi_send_overflow(hp);
519 } 539 }
520 spin_unlock_irqrestore(&hp->lock, flags); 540 spin_unlock_irqrestore(&hp->lock, flags);
521 541
522 tty_kref_put(tty); 542 if (flip) {
543 tty_flip_buffer_push(flip);
544 }
523 545
524 return IRQ_HANDLED; 546 return IRQ_HANDLED;
525} 547}
@@ -715,11 +737,14 @@ static int hvsi_open(struct tty_struct *tty, struct file *filp)
715{ 737{
716 struct hvsi_struct *hp; 738 struct hvsi_struct *hp;
717 unsigned long flags; 739 unsigned long flags;
740 int line = tty->index;
718 int ret; 741 int ret;
719 742
720 pr_debug("%s\n", __func__); 743 pr_debug("%s\n", __func__);
721 744
722 hp = &hvsi_ports[tty->index]; 745 if (line < 0 || line >= hvsi_count)
746 return -ENODEV;
747 hp = &hvsi_ports[line];
723 748
724 tty->driver_data = hp; 749 tty->driver_data = hp;
725 750
@@ -727,9 +752,9 @@ static int hvsi_open(struct tty_struct *tty, struct file *filp)
727 if (hp->state == HVSI_FSP_DIED) 752 if (hp->state == HVSI_FSP_DIED)
728 return -EIO; 753 return -EIO;
729 754
730 tty_port_tty_set(&hp->port, tty);
731 spin_lock_irqsave(&hp->lock, flags); 755 spin_lock_irqsave(&hp->lock, flags);
732 hp->port.count++; 756 hp->tty = tty;
757 hp->count++;
733 atomic_set(&hp->seqno, 0); 758 atomic_set(&hp->seqno, 0);
734 h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE); 759 h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE);
735 spin_unlock_irqrestore(&hp->lock, flags); 760 spin_unlock_irqrestore(&hp->lock, flags);
@@ -765,7 +790,7 @@ static void hvsi_flush_output(struct hvsi_struct *hp)
765 790
766 /* 'writer' could still be pending if it didn't see n_outbuf = 0 yet */ 791 /* 'writer' could still be pending if it didn't see n_outbuf = 0 yet */
767 cancel_delayed_work_sync(&hp->writer); 792 cancel_delayed_work_sync(&hp->writer);
768 flush_work(&hp->handshaker); 793 flush_work_sync(&hp->handshaker);
769 794
770 /* 795 /*
771 * it's also possible that our timeout expired and hvsi_write_worker 796 * it's also possible that our timeout expired and hvsi_write_worker
@@ -786,8 +811,8 @@ static void hvsi_close(struct tty_struct *tty, struct file *filp)
786 811
787 spin_lock_irqsave(&hp->lock, flags); 812 spin_lock_irqsave(&hp->lock, flags);
788 813
789 if (--hp->port.count == 0) { 814 if (--hp->count == 0) {
790 tty_port_tty_set(&hp->port, NULL); 815 hp->tty = NULL;
791 hp->inbuf_end = hp->inbuf; /* discard remaining partial packets */ 816 hp->inbuf_end = hp->inbuf; /* discard remaining partial packets */
792 817
793 /* only close down connection if it is not the console */ 818 /* only close down connection if it is not the console */
@@ -819,9 +844,9 @@ static void hvsi_close(struct tty_struct *tty, struct file *filp)
819 844
820 spin_lock_irqsave(&hp->lock, flags); 845 spin_lock_irqsave(&hp->lock, flags);
821 } 846 }
822 } else if (hp->port.count < 0) 847 } else if (hp->count < 0)
823 printk(KERN_ERR "hvsi_close %lu: oops, count is %d\n", 848 printk(KERN_ERR "hvsi_close %lu: oops, count is %d\n",
824 hp - hvsi_ports, hp->port.count); 849 hp - hvsi_ports, hp->count);
825 850
826 spin_unlock_irqrestore(&hp->lock, flags); 851 spin_unlock_irqrestore(&hp->lock, flags);
827} 852}
@@ -833,11 +858,12 @@ static void hvsi_hangup(struct tty_struct *tty)
833 858
834 pr_debug("%s\n", __func__); 859 pr_debug("%s\n", __func__);
835 860
836 tty_port_tty_set(&hp->port, NULL);
837
838 spin_lock_irqsave(&hp->lock, flags); 861 spin_lock_irqsave(&hp->lock, flags);
839 hp->port.count = 0; 862
863 hp->count = 0;
840 hp->n_outbuf = 0; 864 hp->n_outbuf = 0;
865 hp->tty = NULL;
866
841 spin_unlock_irqrestore(&hp->lock, flags); 867 spin_unlock_irqrestore(&hp->lock, flags);
842} 868}
843 869
@@ -865,7 +891,6 @@ static void hvsi_write_worker(struct work_struct *work)
865{ 891{
866 struct hvsi_struct *hp = 892 struct hvsi_struct *hp =
867 container_of(work, struct hvsi_struct, writer.work); 893 container_of(work, struct hvsi_struct, writer.work);
868 struct tty_struct *tty;
869 unsigned long flags; 894 unsigned long flags;
870#ifdef DEBUG 895#ifdef DEBUG
871 static long start_j = 0; 896 static long start_j = 0;
@@ -899,11 +924,7 @@ static void hvsi_write_worker(struct work_struct *work)
899 start_j = 0; 924 start_j = 0;
900#endif /* DEBUG */ 925#endif /* DEBUG */
901 wake_up_all(&hp->emptyq); 926 wake_up_all(&hp->emptyq);
902 tty = tty_port_tty_get(&hp->port); 927 tty_wakeup(hp->tty);
903 if (tty) {
904 tty_wakeup(tty);
905 tty_kref_put(tty);
906 }
907 } 928 }
908 929
909out: 930out:
@@ -948,8 +969,8 @@ static int hvsi_write(struct tty_struct *tty,
948 * and hvsi_write_worker will be scheduled. subsequent hvsi_write() calls 969 * and hvsi_write_worker will be scheduled. subsequent hvsi_write() calls
949 * will see there is no room in outbuf and return. 970 * will see there is no room in outbuf and return.
950 */ 971 */
951 while ((count > 0) && (hvsi_write_room(tty) > 0)) { 972 while ((count > 0) && (hvsi_write_room(hp->tty) > 0)) {
952 int chunksize = min(count, hvsi_write_room(tty)); 973 int chunksize = min(count, hvsi_write_room(hp->tty));
953 974
954 BUG_ON(hp->n_outbuf < 0); 975 BUG_ON(hp->n_outbuf < 0);
955 memcpy(hp->outbuf + hp->n_outbuf, source, chunksize); 976 memcpy(hp->outbuf + hp->n_outbuf, source, chunksize);
@@ -996,16 +1017,19 @@ static void hvsi_unthrottle(struct tty_struct *tty)
996{ 1017{
997 struct hvsi_struct *hp = tty->driver_data; 1018 struct hvsi_struct *hp = tty->driver_data;
998 unsigned long flags; 1019 unsigned long flags;
1020 int shouldflip = 0;
999 1021
1000 pr_debug("%s\n", __func__); 1022 pr_debug("%s\n", __func__);
1001 1023
1002 spin_lock_irqsave(&hp->lock, flags); 1024 spin_lock_irqsave(&hp->lock, flags);
1003 if (hp->n_throttle) { 1025 if (hp->n_throttle) {
1004 hvsi_send_overflow(hp, tty); 1026 hvsi_send_overflow(hp);
1005 tty_flip_buffer_push(tty); 1027 shouldflip = 1;
1006 } 1028 }
1007 spin_unlock_irqrestore(&hp->lock, flags); 1029 spin_unlock_irqrestore(&hp->lock, flags);
1008 1030
1031 if (shouldflip)
1032 tty_flip_buffer_push(hp->tty);
1009 1033
1010 h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE); 1034 h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE);
1011} 1035}
@@ -1064,6 +1088,7 @@ static int __init hvsi_init(void)
1064 if (!hvsi_driver) 1088 if (!hvsi_driver)
1065 return -ENOMEM; 1089 return -ENOMEM;
1066 1090
1091 hvsi_driver->owner = THIS_MODULE;
1067 hvsi_driver->driver_name = "hvsi"; 1092 hvsi_driver->driver_name = "hvsi";
1068 hvsi_driver->name = "hvsi"; 1093 hvsi_driver->name = "hvsi";
1069 hvsi_driver->major = HVSI_MAJOR; 1094 hvsi_driver->major = HVSI_MAJOR;
@@ -1080,9 +1105,7 @@ static int __init hvsi_init(void)
1080 struct hvsi_struct *hp = &hvsi_ports[i]; 1105 struct hvsi_struct *hp = &hvsi_ports[i];
1081 int ret = 1; 1106 int ret = 1;
1082 1107
1083 tty_port_link_device(&hp->port, hvsi_driver, i); 1108 ret = request_irq(hp->virq, hvsi_interrupt, IRQF_DISABLED, "hvsi", hp);
1084
1085 ret = request_irq(hp->virq, hvsi_interrupt, 0, "hvsi", hp);
1086 if (ret) 1109 if (ret)
1087 printk(KERN_ERR "HVSI: couldn't reserve irq 0x%x (error %i)\n", 1110 printk(KERN_ERR "HVSI: couldn't reserve irq 0x%x (error %i)\n",
1088 hp->virq, ret); 1111 hp->virq, ret);
@@ -1209,16 +1232,14 @@ static int __init hvsi_console_init(void)
1209 init_waitqueue_head(&hp->emptyq); 1232 init_waitqueue_head(&hp->emptyq);
1210 init_waitqueue_head(&hp->stateq); 1233 init_waitqueue_head(&hp->stateq);
1211 spin_lock_init(&hp->lock); 1234 spin_lock_init(&hp->lock);
1212 tty_port_init(&hp->port);
1213 hp->index = hvsi_count; 1235 hp->index = hvsi_count;
1214 hp->inbuf_end = hp->inbuf; 1236 hp->inbuf_end = hp->inbuf;
1215 hp->state = HVSI_CLOSED; 1237 hp->state = HVSI_CLOSED;
1216 hp->vtermno = *vtermno; 1238 hp->vtermno = *vtermno;
1217 hp->virq = irq_create_mapping(NULL, irq[0]); 1239 hp->virq = irq_create_mapping(NULL, irq[0]);
1218 if (hp->virq == 0) { 1240 if (hp->virq == NO_IRQ) {
1219 printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", 1241 printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n",
1220 __func__, irq[0]); 1242 __func__, irq[0]);
1221 tty_port_destroy(&hp->port);
1222 continue; 1243 continue;
1223 } 1244 }
1224 1245
diff --git a/drivers/tty/hvc/hvsi_lib.c b/drivers/tty/hvc/hvsi_lib.c
index 3396eb9d57a..bd9b09827b2 100644
--- a/drivers/tty/hvc/hvsi_lib.c
+++ b/drivers/tty/hvc/hvsi_lib.c
@@ -183,7 +183,7 @@ int hvsilib_get_chars(struct hvsi_priv *pv, char *buf, int count)
183 unsigned int tries, read = 0; 183 unsigned int tries, read = 0;
184 184
185 if (WARN_ON(!pv)) 185 if (WARN_ON(!pv))
186 return -ENXIO; 186 return 0;
187 187
188 /* If we aren't open, don't do anything in order to avoid races 188 /* If we aren't open, don't do anything in order to avoid races
189 * with connection establishment. The hvc core will call this 189 * with connection establishment. The hvc core will call this
@@ -234,7 +234,7 @@ int hvsilib_put_chars(struct hvsi_priv *pv, const char *buf, int count)
234 int rc, adjcount = min(count, HVSI_MAX_OUTGOING_DATA); 234 int rc, adjcount = min(count, HVSI_MAX_OUTGOING_DATA);
235 235
236 if (WARN_ON(!pv)) 236 if (WARN_ON(!pv))
237 return -ENODEV; 237 return 0;
238 238
239 dp.hdr.type = VS_DATA_PACKET_HEADER; 239 dp.hdr.type = VS_DATA_PACKET_HEADER;
240 dp.hdr.len = adjcount + sizeof(struct hvsi_header); 240 dp.hdr.len = adjcount + sizeof(struct hvsi_header);
@@ -377,7 +377,7 @@ int hvsilib_open(struct hvsi_priv *pv, struct hvc_struct *hp)
377 pr_devel("HVSI@%x: open !\n", pv->termno); 377 pr_devel("HVSI@%x: open !\n", pv->termno);
378 378
379 /* Keep track of the tty data structure */ 379 /* Keep track of the tty data structure */
380 pv->tty = tty_port_tty_get(&hp->port); 380 pv->tty = tty_kref_get(hp->tty);
381 381
382 hvsilib_establish(pv); 382 hvsilib_establish(pv);
383 383
@@ -400,7 +400,7 @@ void hvsilib_close(struct hvsi_priv *pv, struct hvc_struct *hp)
400 spin_unlock_irqrestore(&hp->lock, flags); 400 spin_unlock_irqrestore(&hp->lock, flags);
401 401
402 /* Clear our own DTR */ 402 /* Clear our own DTR */
403 if (!pv->tty || (pv->tty->termios.c_cflag & HUPCL)) 403 if (!pv->tty || (pv->tty->termios->c_cflag & HUPCL))
404 hvsilib_write_mctrl(pv, 0); 404 hvsilib_write_mctrl(pv, 0);
405 405
406 /* Tear down the connection */ 406 /* Tear down the connection */