aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/tty/hvc/Kconfig8
-rw-r--r--drivers/tty/hvc/hvc_xen.c116
2 files changed, 70 insertions, 54 deletions
diff --git a/drivers/tty/hvc/Kconfig b/drivers/tty/hvc/Kconfig
index 4222035acfb7..192e21e2239c 100644
--- a/drivers/tty/hvc/Kconfig
+++ b/drivers/tty/hvc/Kconfig
@@ -76,6 +76,14 @@ config HVC_XEN
76 help 76 help
77 Xen virtual console device driver 77 Xen virtual console device driver
78 78
79config HVC_XEN_FRONTEND
80 bool "Xen Hypervisor Multiple Consoles support"
81 depends on HVC_XEN
82 select XEN_XENBUS_FRONTEND
83 default y
84 help
85 Xen driver for secondary virtual consoles
86
79config HVC_UDBG 87config HVC_UDBG
80 bool "udbg based fake hypervisor console" 88 bool "udbg based fake hypervisor console"
81 depends on PPC && EXPERIMENTAL 89 depends on PPC && EXPERIMENTAL
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
index 26090c736bcf..83d5c88e7165 100644
--- a/drivers/tty/hvc/hvc_xen.c
+++ b/drivers/tty/hvc/hvc_xen.c
@@ -55,7 +55,6 @@ struct xencons_info {
55 55
56static LIST_HEAD(xenconsoles); 56static LIST_HEAD(xenconsoles);
57static DEFINE_SPINLOCK(xencons_lock); 57static DEFINE_SPINLOCK(xencons_lock);
58static struct xenbus_driver xencons_driver;
59 58
60/* ------------------------------------------------------------------ */ 59/* ------------------------------------------------------------------ */
61 60
@@ -298,53 +297,6 @@ static int xen_initial_domain_console_init(void)
298 return 0; 297 return 0;
299} 298}
300 299
301static int __init xen_hvc_init(void)
302{
303 int r;
304 struct xencons_info *info;
305 const struct hv_ops *ops;
306
307 if (!xen_domain())
308 return -ENODEV;
309
310 if (xen_initial_domain()) {
311 ops = &dom0_hvc_ops;
312 r = xen_initial_domain_console_init();
313 if (r < 0)
314 return r;
315 info = vtermno_to_xencons(HVC_COOKIE);
316 } else {
317 ops = &domU_hvc_ops;
318 if (xen_hvm_domain())
319 r = xen_hvm_console_init();
320 else
321 r = xen_pv_console_init();
322 if (r < 0)
323 return r;
324
325 info = vtermno_to_xencons(HVC_COOKIE);
326 info->irq = bind_evtchn_to_irq(info->evtchn);
327 }
328 if (info->irq < 0)
329 info->irq = 0; /* NO_IRQ */
330 else
331 irq_set_noprobe(info->irq);
332
333 info->hvc = hvc_alloc(HVC_COOKIE, info->irq, ops, 256);
334 if (IS_ERR(info->hvc)) {
335 r = PTR_ERR(info->hvc);
336 spin_lock(&xencons_lock);
337 list_del(&info->list);
338 spin_unlock(&xencons_lock);
339 if (info->irq)
340 unbind_from_irqhandler(info->irq, NULL);
341 kfree(info);
342 return r;
343 }
344
345 return xenbus_register_frontend(&xencons_driver);
346}
347
348void xen_console_resume(void) 300void xen_console_resume(void)
349{ 301{
350 struct xencons_info *info = vtermno_to_xencons(HVC_COOKIE); 302 struct xencons_info *info = vtermno_to_xencons(HVC_COOKIE);
@@ -392,6 +344,9 @@ static int xen_console_remove(struct xencons_info *info)
392 return 0; 344 return 0;
393} 345}
394 346
347#ifdef CONFIG_HVC_XEN_FRONTEND
348static struct xenbus_driver xencons_driver;
349
395static int xencons_remove(struct xenbus_device *dev) 350static int xencons_remove(struct xenbus_device *dev)
396{ 351{
397 return xen_console_remove(dev_get_drvdata(&dev->dev)); 352 return xen_console_remove(dev_get_drvdata(&dev->dev));
@@ -543,6 +498,65 @@ static const struct xenbus_device_id xencons_ids[] = {
543}; 498};
544 499
545 500
501static DEFINE_XENBUS_DRIVER(xencons, "xenconsole",
502 .probe = xencons_probe,
503 .remove = xencons_remove,
504 .resume = xencons_resume,
505 .otherend_changed = xencons_backend_changed,
506);
507#endif /* CONFIG_HVC_XEN_FRONTEND */
508
509static int __init xen_hvc_init(void)
510{
511 int r;
512 struct xencons_info *info;
513 const struct hv_ops *ops;
514
515 if (!xen_domain())
516 return -ENODEV;
517
518 if (xen_initial_domain()) {
519 ops = &dom0_hvc_ops;
520 r = xen_initial_domain_console_init();
521 if (r < 0)
522 return r;
523 info = vtermno_to_xencons(HVC_COOKIE);
524 } else {
525 ops = &domU_hvc_ops;
526 if (xen_hvm_domain())
527 r = xen_hvm_console_init();
528 else
529 r = xen_pv_console_init();
530 if (r < 0)
531 return r;
532
533 info = vtermno_to_xencons(HVC_COOKIE);
534 info->irq = bind_evtchn_to_irq(info->evtchn);
535 }
536 if (info->irq < 0)
537 info->irq = 0; /* NO_IRQ */
538 else
539 irq_set_noprobe(info->irq);
540
541 info->hvc = hvc_alloc(HVC_COOKIE, info->irq, ops, 256);
542 if (IS_ERR(info->hvc)) {
543 r = PTR_ERR(info->hvc);
544 spin_lock(&xencons_lock);
545 list_del(&info->list);
546 spin_unlock(&xencons_lock);
547 if (info->irq)
548 unbind_from_irqhandler(info->irq, NULL);
549 kfree(info);
550 return r;
551 }
552
553 r = 0;
554#ifdef CONFIG_HVC_XEN_FRONTEND
555 r = xenbus_register_frontend(&xencons_driver);
556#endif
557 return r;
558}
559
546static void __exit xen_hvc_fini(void) 560static void __exit xen_hvc_fini(void)
547{ 561{
548 struct xencons_info *entry, *next; 562 struct xencons_info *entry, *next;
@@ -580,12 +594,6 @@ static int xen_cons_init(void)
580 return 0; 594 return 0;
581} 595}
582 596
583static DEFINE_XENBUS_DRIVER(xencons, "xenconsole",
584 .probe = xencons_probe,
585 .remove = xencons_remove,
586 .resume = xencons_resume,
587 .otherend_changed = xencons_backend_changed,
588);
589 597
590module_init(xen_hvc_init); 598module_init(xen_hvc_init);
591module_exit(xen_hvc_fini); 599module_exit(xen_hvc_fini);