X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=common%2Fserial.c;h=5b83d6ae71f288800e54fc13fc0e4e07a836e860;hb=dee17768d4f0490650cb5f28e2366fe0f690fa06;hp=41a24c2fadc666f148ec4dabd69c559dbc572c48;hpb=cb32ed1fc298875845f166d326a3f2704a0d5364;p=u-boot diff --git a/common/serial.c b/common/serial.c index 41a24c2fad..5b83d6ae71 100644 --- a/common/serial.c +++ b/common/serial.c @@ -24,74 +24,27 @@ #include #include #include +#include +#include DECLARE_GLOBAL_DATA_PTR; static struct serial_device *serial_devices = NULL; static struct serial_device *serial_current = NULL; -#if !defined(CONFIG_LWMON) && !defined(CONFIG_PXA27X) -struct serial_device *__default_serial_console (void) -{ -#if defined(CONFIG_8xx_CONS_SMC1) || defined(CONFIG_8xx_CONS_SMC2) - return &serial_smc_device; -#elif defined(CONFIG_8xx_CONS_SCC1) || defined(CONFIG_8xx_CONS_SCC2) \ - || defined(CONFIG_8xx_CONS_SCC3) || defined(CONFIG_8xx_CONS_SCC4) - return &serial_scc_device; -#elif defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \ - || defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX) \ - || defined(CONFIG_MPC5xxx) || defined(CONFIG_MPC83xx) \ - || defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) -#if defined(CONFIG_CONS_INDEX) && defined(CONFIG_SYS_NS16550_SERIAL) -#if (CONFIG_CONS_INDEX==1) - return &eserial1_device; -#elif (CONFIG_CONS_INDEX==2) - return &eserial2_device; -#elif (CONFIG_CONS_INDEX==3) - return &eserial3_device; -#elif (CONFIG_CONS_INDEX==4) - return &eserial4_device; -#else -#error "Bad CONFIG_CONS_INDEX." -#endif -#elif defined(CONFIG_UART1_CONSOLE) - return &serial1_device; -#else - return &serial0_device; -#endif -#elif defined(CONFIG_S3C2410) -#if defined(CONFIG_SERIAL1) - return &s3c24xx_serial0_device; -#elif defined(CONFIG_SERIAL2) - return &s3c24xx_serial1_device; -#elif defined(CONFIG_SERIAL3) - return &s3c24xx_serial2_device; -#else -#error "CONFIG_SERIAL? missing." -#endif -#elif defined(CONFIG_OMAP3_ZOOM2) - return ZOOM2_DEFAULT_SERIAL_DEVICE; -#else -#error No default console -#endif -} - -struct serial_device *default_serial_console(void) __attribute__((weak, alias("__default_serial_console"))); -#endif - -int serial_register (struct serial_device *dev) +void serial_register(struct serial_device *dev) { +#ifdef CONFIG_NEEDS_MANUAL_RELOC dev->init += gd->reloc_off; dev->setbrg += gd->reloc_off; dev->getc += gd->reloc_off; dev->tstc += gd->reloc_off; dev->putc += gd->reloc_off; dev->puts += gd->reloc_off; +#endif dev->next = serial_devices; serial_devices = dev; - - return 0; } void serial_initialize (void) @@ -104,13 +57,6 @@ void serial_initialize (void) serial_register (&serial_scc_device); #endif -#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) \ - || defined(CONFIG_405EP) || defined(CONFIG_405EZ) || defined(CONFIG_405EX) \ - || defined(CONFIG_MPC5xxx) - serial_register(&serial0_device); - serial_register(&serial1_device); -#endif - #if defined(CONFIG_SYS_NS16550_SERIAL) #if defined(CONFIG_SYS_NS16550_COM1) serial_register(&eserial1_device); @@ -139,6 +85,43 @@ void serial_initialize (void) serial_register(&s3c24xx_serial1_device); serial_register(&s3c24xx_serial2_device); #endif +#if defined(CONFIG_S5P) + serial_register(&s5p_serial0_device); + serial_register(&s5p_serial1_device); + serial_register(&s5p_serial2_device); + serial_register(&s5p_serial3_device); +#endif +#if defined(CONFIG_MPC512X) +#if defined(CONFIG_SYS_PSC1) + serial_register(&serial1_device); +#endif +#if defined(CONFIG_SYS_PSC3) + serial_register(&serial3_device); +#endif +#if defined(CONFIG_SYS_PSC4) + serial_register(&serial4_device); +#endif +#if defined(CONFIG_SYS_PSC6) + serial_register(&serial6_device); +#endif +#endif +#if defined(CONFIG_SYS_BFIN_UART) + serial_register_bfin_uart(); +#endif +#if defined(CONFIG_XILINX_UARTLITE) +# ifdef XILINX_UARTLITE_BASEADDR + serial_register(&uartlite_serial0_device); +# endif /* XILINX_UARTLITE_BASEADDR */ +# ifdef XILINX_UARTLITE_BASEADDR1 + serial_register(&uartlite_serial1_device); +# endif /* XILINX_UARTLITE_BASEADDR1 */ +# ifdef XILINX_UARTLITE_BASEADDR2 + serial_register(&uartlite_serial2_device); +# endif /* XILINX_UARTLITE_BASEADDR2 */ +# ifdef XILINX_UARTLITE_BASEADDR3 + serial_register(&uartlite_serial3_device); +# endif /* XILINX_UARTLITE_BASEADDR3 */ +#endif /* CONFIG_XILINX_UARTLITE */ serial_assign (default_serial_console ()->name); } @@ -154,6 +137,7 @@ void serial_stdio_init (void) dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; dev.start = s->init; + dev.stop = s->uninit; dev.putc = s->putc; dev.puts = s->puts; dev.getc = s->getc; @@ -188,71 +172,135 @@ void serial_reinit_all (void) } } -int serial_init (void) +static struct serial_device *get_current(void) { - if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { - struct serial_device *dev = default_serial_console (); + struct serial_device *dev; - return dev->init (); - } + if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { + dev = default_serial_console(); + + /* We must have a console device */ + if (!dev) + panic("Cannot find console"); + } else + dev = serial_current; + return dev; +} - return serial_current->init (); +int serial_init(void) +{ + return get_current()->init(); } void serial_setbrg (void) { - if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { - struct serial_device *dev = default_serial_console (); - - dev->setbrg (); - return; - } - - serial_current->setbrg (); + get_current()->setbrg(); } int serial_getc (void) { - if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { - struct serial_device *dev = default_serial_console (); - - return dev->getc (); - } - - return serial_current->getc (); + return get_current()->getc(); } int serial_tstc (void) { - if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { - struct serial_device *dev = default_serial_console (); - - return dev->tstc (); - } - - return serial_current->tstc (); + return get_current()->tstc(); } void serial_putc (const char c) { - if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { - struct serial_device *dev = default_serial_console (); - - dev->putc (c); - return; - } - - serial_current->putc (c); + get_current()->putc(c); } void serial_puts (const char *s) { - if (!(gd->flags & GD_FLG_RELOC) || !serial_current) { - struct serial_device *dev = default_serial_console (); + get_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; - dev->puts (s); - return; + /* 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(); } - serial_current->puts (s); + done: + /* Restore previous serial state */ + serial_current = saved_dev; + bd->bi_baudrate = saved_baud; + serial_reinit_all(); + serial_setbrg(); + + return ret; } +#endif