]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/tty/hvc/hvc_opal.c
Merge branch 'spectre' of git://git.armlinux.org.uk/~rmk/linux-arm
[linux.git] / drivers / tty / hvc / hvc_opal.c
index 9645c0062a900e2385b63cccdf203f7f82b7f0bb..77baf895108fac45252ed6f3ea1b8b5557cbee91 100644 (file)
@@ -52,6 +52,7 @@ static u32 hvc_opal_boot_termno;
 static const struct hv_ops hvc_opal_raw_ops = {
        .get_chars = opal_get_chars,
        .put_chars = opal_put_chars,
+       .flush = opal_flush_chars,
        .notifier_add = notifier_add_irq,
        .notifier_del = notifier_del_irq,
        .notifier_hangup = notifier_hangup_irq,
@@ -141,6 +142,7 @@ static int hvc_opal_hvsi_tiocmset(struct hvc_struct *hp, unsigned int set,
 static const struct hv_ops hvc_opal_hvsi_ops = {
        .get_chars = hvc_opal_hvsi_get_chars,
        .put_chars = hvc_opal_hvsi_put_chars,
+       .flush = opal_flush_chars,
        .notifier_add = hvc_opal_hvsi_open,
        .notifier_del = hvc_opal_hvsi_close,
        .notifier_hangup = hvc_opal_hvsi_hangup,
@@ -183,9 +185,15 @@ static int hvc_opal_probe(struct platform_device *dev)
                        return -ENOMEM;
                pv->proto = proto;
                hvc_opal_privs[termno] = pv;
-               if (proto == HV_PROTOCOL_HVSI)
-                       hvsilib_init(&pv->hvsi, opal_get_chars, opal_put_chars,
+               if (proto == HV_PROTOCOL_HVSI) {
+                       /*
+                        * We want put_chars to be atomic to avoid mangling of
+                        * hvsi packets.
+                        */
+                       hvsilib_init(&pv->hvsi,
+                                    opal_get_chars, opal_put_chars_atomic,
                                     termno, 0);
+               }
 
                /* Instanciate now to establish a mapping index==vtermno */
                hvc_instantiate(termno, termno, ops);
@@ -275,6 +283,11 @@ static void udbg_opal_putc(char c)
                        count = hvc_opal_hvsi_put_chars(termno, &c, 1);
                        break;
                }
+
+               /* This is needed for the cosole to flush
+                * when there aren't any interrupts.
+                */
+               opal_flush_console(termno);
        } while(count == 0 || count == -EAGAIN);
 }
 
@@ -302,14 +315,8 @@ static int udbg_opal_getc(void)
        int ch;
        for (;;) {
                ch = udbg_opal_getc_poll();
-               if (ch == -1) {
-                       /* This shouldn't be needed...but... */
-                       volatile unsigned long delay;
-                       for (delay=0; delay < 2000000; delay++)
-                               ;
-               } else {
+               if (ch != -1)
                        return ch;
-               }
        }
 }
 
@@ -370,8 +377,9 @@ void __init hvc_opal_init_early(void)
        else if (of_device_is_compatible(stdout_node,"ibm,opal-console-hvsi")) {
                hvc_opal_boot_priv.proto = HV_PROTOCOL_HVSI;
                ops = &hvc_opal_hvsi_ops;
-               hvsilib_init(&hvc_opal_boot_priv.hvsi, opal_get_chars,
-                            opal_put_chars, index, 1);
+               hvsilib_init(&hvc_opal_boot_priv.hvsi,
+                            opal_get_chars, opal_put_chars_atomic,
+                            index, 1);
                /* HVSI, perform the handshake now */
                hvsilib_establish(&hvc_opal_boot_priv.hvsi);
                pr_devel("hvc_opal: Found HVSI console\n");
@@ -403,7 +411,8 @@ void __init udbg_init_debug_opal_hvsi(void)
        hvc_opal_privs[index] = &hvc_opal_boot_priv;
        hvc_opal_boot_termno = index;
        udbg_init_opal_common();
-       hvsilib_init(&hvc_opal_boot_priv.hvsi, opal_get_chars, opal_put_chars,
+       hvsilib_init(&hvc_opal_boot_priv.hvsi,
+                    opal_get_chars, opal_put_chars_atomic,
                     index, 1);
        hvsilib_establish(&hvc_opal_boot_priv.hvsi);
 }