Merge branch 'bkl-removal' into next
[pandora-kernel.git] / drivers / char / hvc_xen.c
index e97d9d1..db2ae42 100644 (file)
@@ -39,9 +39,14 @@ static int xencons_irq;
 
 /* ------------------------------------------------------------------ */
 
+static unsigned long console_pfn = ~0ul;
+
 static inline struct xencons_interface *xencons_interface(void)
 {
-       return mfn_to_virt(xen_start_info->console.domU.mfn);
+       if (console_pfn == ~0ul)
+               return mfn_to_virt(xen_start_info->console.domU.mfn);
+       else
+               return __va(console_pfn << PAGE_SHIFT);
 }
 
 static inline void notify_daemon(void)
@@ -101,20 +106,32 @@ static int __init xen_init(void)
 {
        struct hvc_struct *hp;
 
-       if (!is_running_on_xen())
-               return 0;
+       if (!is_running_on_xen() ||
+           is_initial_xendomain() ||
+           !xen_start_info->console.domU.evtchn)
+               return -ENODEV;
 
        xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn);
        if (xencons_irq < 0)
-               xencons_irq = 0 /* NO_IRQ */;
+               xencons_irq = 0; /* NO_IRQ */
+
        hp = hvc_alloc(HVC_COOKIE, xencons_irq, &hvc_ops, 256);
        if (IS_ERR(hp))
                return PTR_ERR(hp);
 
        hvc = hp;
+
+       console_pfn = mfn_to_pfn(xen_start_info->console.domU.mfn);
+
        return 0;
 }
 
+void xen_console_resume(void)
+{
+       if (xencons_irq)
+               rebind_evtchn_irq(xen_start_info->console.domU.evtchn, xencons_irq);
+}
+
 static void __exit xen_fini(void)
 {
        if (hvc)
@@ -134,12 +151,28 @@ module_init(xen_init);
 module_exit(xen_fini);
 console_initcall(xen_cons_init);
 
+static void raw_console_write(const char *str, int len)
+{
+       while(len > 0) {
+               int rc = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)str);
+               if (rc <= 0)
+                       break;
+
+               str += rc;
+               len -= rc;
+       }
+}
+
+#ifdef CONFIG_EARLY_PRINTK
 static void xenboot_write_console(struct console *console, const char *string,
                                  unsigned len)
 {
        unsigned int linelen, off = 0;
        const char *pos;
 
+       raw_console_write(string, len);
+
+       write_console(0, "(early) ", 8);
        while (off < len && NULL != (pos = strchr(string+off, '\n'))) {
                linelen = pos-string+off;
                if (off + linelen > len)
@@ -155,21 +188,13 @@ static void xenboot_write_console(struct console *console, const char *string,
 struct console xenboot_console = {
        .name           = "xenboot",
        .write          = xenboot_write_console,
-       .flags          = CON_PRINTBUFFER | CON_BOOT,
+       .flags          = CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME,
 };
+#endif /* CONFIG_EARLY_PRINTK */
 
 void xen_raw_console_write(const char *str)
 {
-       int len = strlen(str);
-
-       while(len > 0) {
-               int rc = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)str);
-               if (rc <= 0)
-                       break;
-
-               str += rc;
-               len -= rc;
-       }
+       raw_console_write(str, strlen(str));
 }
 
 void xen_raw_printk(const char *fmt, ...)