Merge branch 'drm-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
[cascardo/linux.git] / arch / x86 / boot / tty.c
index 01ec69c..def2451 100644 (file)
  * ----------------------------------------------------------------------- */
 
 /*
- * Very simple screen I/O
- * XXX: Probably should add very simple serial I/O?
+ * Very simple screen and serial I/O
  */
 
 #include "boot.h"
 
+int early_serial_base;
+
+#define XMTRDY          0x20
+
+#define TXR             0       /*  Transmit register (WRITE) */
+#define LSR             5       /*  Line Status               */
+
 /*
  * These functions are in .inittext so they can be used to signal
  * error during initialization.
  */
 
-void __attribute__((section(".inittext"))) putchar(int ch)
+static void __attribute__((section(".inittext"))) serial_putchar(int ch)
 {
-       struct biosregs ireg;
+       unsigned timeout = 0xffff;
 
-       if (ch == '\n')
-               putchar('\r');  /* \n -> \r\n */
+       while ((inb(early_serial_base + LSR) & XMTRDY) == 0 && --timeout)
+               cpu_relax();
+
+       outb(ch, early_serial_base + TXR);
+}
+
+static void __attribute__((section(".inittext"))) bios_putchar(int ch)
+{
+       struct biosregs ireg;
 
        initregs(&ireg);
        ireg.bx = 0x0007;
@@ -36,6 +49,17 @@ void __attribute__((section(".inittext"))) putchar(int ch)
        intcall(0x10, &ireg, NULL);
 }
 
+void __attribute__((section(".inittext"))) putchar(int ch)
+{
+       if (ch == '\n')
+               putchar('\r');  /* \n -> \r\n */
+
+       bios_putchar(ch);
+
+       if (early_serial_base != 0)
+               serial_putchar(ch);
+}
+
 void __attribute__((section(".inittext"))) puts(const char *str)
 {
        while (*str)
@@ -112,3 +136,4 @@ int getchar_timeout(void)
 
        return 0;               /* Timeout! */
 }
+