#include <common.h>
 #include <serial.h>
 #include <stdio_dev.h>
+#include <post.h>
+#include <linux/compiler.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
 
        serial_current->puts (s);
 }
+
+#if CONFIG_POST & CONFIG_SYS_POST_UART
+static const int bauds[] = CONFIG_SYS_BAUDRATE_TABLE;
+
+/* Mark weak until post/cpu/.../uart.c migrate over */
+__weak
+int uart_post_test(int flags)
+{
+       unsigned char c;
+       int ret, saved_baud, b;
+       struct serial_device *saved_dev, *s;
+       bd_t *bd = gd->bd;
+
+       /* Save current serial state */
+       ret = 0;
+       saved_dev = serial_current;
+       saved_baud = bd->bi_baudrate;
+
+       for (s = serial_devices; s; s = s->next) {
+               /* If this driver doesn't support loop back, skip it */
+               if (!s->loop)
+                       continue;
+
+               /* Test the next device */
+               serial_current = s;
+
+               ret = serial_init();
+               if (ret)
+                       goto done;
+
+               /* Consume anything that happens to be queued */
+               while (serial_tstc())
+                       serial_getc();
+
+               /* Enable loop back */
+               s->loop(1);
+
+               /* Test every available baud rate */
+               for (b = 0; b < ARRAY_SIZE(bauds); ++b) {
+                       bd->bi_baudrate = bauds[b];
+                       serial_setbrg();
+
+                       /*
+                        * Stick to printable chars to avoid issues:
+                        *  - terminal corruption
+                        *  - serial program reacting to sequences and sending
+                        *    back random extra data
+                        *  - most serial drivers add in extra chars (like \r\n)
+                        */
+                       for (c = 0x20; c < 0x7f; ++c) {
+                               /* Send it out */
+                               serial_putc(c);
+
+                               /* Make sure it's the same one */
+                               ret = (c != serial_getc());
+                               if (ret) {
+                                       s->loop(0);
+                                       goto done;
+                               }
+
+                               /* Clean up the output in case it was sent */
+                               serial_putc('\b');
+                               ret = ('\b' != serial_getc());
+                               if (ret) {
+                                       s->loop(0);
+                                       goto done;
+                               }
+                       }
+               }
+
+               /* Disable loop back */
+               s->loop(0);
+
+               /* XXX: There is no serial_uninit() !? */
+               if (s->uninit)
+                       s->uninit();
+       }
+
+ done:
+       /* Restore previous serial state */
+       serial_current = saved_dev;
+       bd->bi_baudrate = saved_baud;
+       serial_reinit_all();
+       serial_setbrg();
+
+       return ret;
+}
+#endif