aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/bfin_5xx.c
diff options
context:
space:
mode:
authorRobin Getz <robin.getz@analog.com>2007-10-09 05:24:49 -0400
committerBryan Wu <bryan.wu@analog.com>2007-10-09 05:24:49 -0400
commit0ae53640b54f2c30e52044f7102ba08915b988a7 (patch)
treec8d89d9856d994e0069fe3dbe9687b96c7a79162 /drivers/serial/bfin_5xx.c
parent1d487f468de75b8a5c664db60e106935f9dc753b (diff)
Blackfin arch: Initial patch to add earlyprintk support
This allows debugging of problems which happen eary in the kernel boot process (after bootargs are parsed, but before serial subsystem is fully initialized) Signed-off-by: Robin Getz <robin.getz@analog.com> Signed-off-by: Bryan Wu <bryan.wu@analog.com>
Diffstat (limited to 'drivers/serial/bfin_5xx.c')
-rw-r--r--drivers/serial/bfin_5xx.c129
1 files changed, 101 insertions, 28 deletions
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 1e79ee605d93..5039e2675abc 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -962,30 +962,6 @@ static void __init bfin_serial_init_ports(void)
962} 962}
963 963
964#ifdef CONFIG_SERIAL_BFIN_CONSOLE 964#ifdef CONFIG_SERIAL_BFIN_CONSOLE
965static void bfin_serial_console_putchar(struct uart_port *port, int ch)
966{
967 struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
968 while (!(UART_GET_LSR(uart) & THRE))
969 barrier();
970 UART_PUT_CHAR(uart, ch);
971 SSYNC();
972}
973
974/*
975 * Interrupts are disabled on entering
976 */
977static void
978bfin_serial_console_write(struct console *co, const char *s, unsigned int count)
979{
980 struct bfin_serial_port *uart = &bfin_serial_ports[co->index];
981 int flags = 0;
982
983 spin_lock_irqsave(&uart->port.lock, flags);
984 uart_console_write(&uart->port, s, count, bfin_serial_console_putchar);
985 spin_unlock_irqrestore(&uart->port.lock, flags);
986
987}
988
989/* 965/*
990 * If the port was already initialised (eg, by a boot loader), 966 * If the port was already initialised (eg, by a boot loader),
991 * try to determine the current setup. 967 * try to determine the current setup.
@@ -1038,19 +1014,25 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
1038 } 1014 }
1039 pr_debug("%s:baud = %d, parity = %c, bits= %d\n", __FUNCTION__, *baud, *parity, *bits); 1015 pr_debug("%s:baud = %d, parity = %c, bits= %d\n", __FUNCTION__, *baud, *parity, *bits);
1040} 1016}
1017#endif
1018
1019#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
1020static struct uart_driver bfin_serial_reg;
1041 1021
1042static int __init 1022static int __init
1043bfin_serial_console_setup(struct console *co, char *options) 1023bfin_serial_console_setup(struct console *co, char *options)
1044{ 1024{
1045 struct bfin_serial_port *uart; 1025 struct bfin_serial_port *uart;
1026# ifdef CONFIG_SERIAL_BFIN_CONSOLE
1046 int baud = 57600; 1027 int baud = 57600;
1047 int bits = 8; 1028 int bits = 8;
1048 int parity = 'n'; 1029 int parity = 'n';
1049#ifdef CONFIG_SERIAL_BFIN_CTSRTS 1030# ifdef CONFIG_SERIAL_BFIN_CTSRTS
1050 int flow = 'r'; 1031 int flow = 'r';
1051#else 1032# else
1052 int flow = 'n'; 1033 int flow = 'n';
1053#endif 1034# endif
1035# endif
1054 1036
1055 /* 1037 /*
1056 * Check whether an invalid uart number has been specified, and 1038 * Check whether an invalid uart number has been specified, and
@@ -1061,15 +1043,45 @@ bfin_serial_console_setup(struct console *co, char *options)
1061 co->index = 0; 1043 co->index = 0;
1062 uart = &bfin_serial_ports[co->index]; 1044 uart = &bfin_serial_ports[co->index];
1063 1045
1046# ifdef CONFIG_SERIAL_BFIN_CONSOLE
1064 if (options) 1047 if (options)
1065 uart_parse_options(options, &baud, &parity, &bits, &flow); 1048 uart_parse_options(options, &baud, &parity, &bits, &flow);
1066 else 1049 else
1067 bfin_serial_console_get_options(uart, &baud, &parity, &bits); 1050 bfin_serial_console_get_options(uart, &baud, &parity, &bits);
1068 1051
1069 return uart_set_options(&uart->port, co, baud, parity, bits, flow); 1052 return uart_set_options(&uart->port, co, baud, parity, bits, flow);
1053# else
1054 return 0;
1055# endif
1056}
1057#endif /* defined (CONFIG_SERIAL_BFIN_CONSOLE) ||
1058 defined (CONFIG_EARLY_PRINTK) */
1059
1060#ifdef CONFIG_SERIAL_BFIN_CONSOLE
1061static void bfin_serial_console_putchar(struct uart_port *port, int ch)
1062{
1063 struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
1064 while (!(UART_GET_LSR(uart) & THRE))
1065 barrier();
1066 UART_PUT_CHAR(uart, ch);
1067 SSYNC();
1068}
1069
1070/*
1071 * Interrupts are disabled on entering
1072 */
1073static void
1074bfin_serial_console_write(struct console *co, const char *s, unsigned int count)
1075{
1076 struct bfin_serial_port *uart = &bfin_serial_ports[co->index];
1077 int flags = 0;
1078
1079 spin_lock_irqsave(&uart->port.lock, flags);
1080 uart_console_write(&uart->port, s, count, bfin_serial_console_putchar);
1081 spin_unlock_irqrestore(&uart->port.lock, flags);
1082
1070} 1083}
1071 1084
1072static struct uart_driver bfin_serial_reg;
1073static struct console bfin_serial_console = { 1085static struct console bfin_serial_console = {
1074 .name = BFIN_SERIAL_NAME, 1086 .name = BFIN_SERIAL_NAME,
1075 .write = bfin_serial_console_write, 1087 .write = bfin_serial_console_write,
@@ -1095,7 +1107,68 @@ console_initcall(bfin_serial_rs_console_init);
1095#define BFIN_SERIAL_CONSOLE &bfin_serial_console 1107#define BFIN_SERIAL_CONSOLE &bfin_serial_console
1096#else 1108#else
1097#define BFIN_SERIAL_CONSOLE NULL 1109#define BFIN_SERIAL_CONSOLE NULL
1110#endif /* CONFIG_SERIAL_BFIN_CONSOLE */
1111
1112
1113#ifdef CONFIG_EARLY_PRINTK
1114static __init void early_serial_putc(struct uart_port *port, int ch)
1115{
1116 unsigned timeout = 0xffff;
1117 struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
1118
1119 while ((!(UART_GET_LSR(uart) & THRE)) && --timeout)
1120 cpu_relax();
1121 UART_PUT_CHAR(uart, ch);
1122}
1123
1124static __init void early_serial_write(struct console *con, const char *s,
1125 unsigned int n)
1126{
1127 struct bfin_serial_port *uart = &bfin_serial_ports[con->index];
1128 unsigned int i;
1129
1130 for (i = 0; i < n; i++, s++) {
1131 if (*s == '\n')
1132 early_serial_putc(&uart->port, '\r');
1133 early_serial_putc(&uart->port, *s);
1134 }
1135}
1136
1137static struct __init console bfin_early_serial_console = {
1138 .name = "early_BFuart",
1139 .write = early_serial_write,
1140 .device = uart_console_device,
1141 .flags = CON_PRINTBUFFER,
1142 .setup = bfin_serial_console_setup,
1143 .index = -1,
1144 .data = &bfin_serial_reg,
1145};
1146
1147struct console __init *bfin_earlyserial_init(unsigned int port,
1148 unsigned int cflag)
1149{
1150 struct bfin_serial_port *uart;
1151 struct ktermios t;
1152
1153 if (port == -1 || port >= nr_ports)
1154 port = 0;
1155 bfin_serial_init_ports();
1156 bfin_early_serial_console.index = port;
1157#ifdef CONFIG_KGDB_UART
1158 kgdb_entry_state = 0;
1159 init_kgdb_uart();
1098#endif 1160#endif
1161 uart = &bfin_serial_ports[port];
1162 t.c_cflag = cflag;
1163 t.c_iflag = 0;
1164 t.c_oflag = 0;
1165 t.c_lflag = ICANON;
1166 t.c_line = port;
1167 bfin_serial_set_termios(&uart->port, &t, &t);
1168 return &bfin_early_serial_console;
1169}
1170
1171#endif /* CONFIG_SERIAL_BFIN_CONSOLE */
1099 1172
1100static struct uart_driver bfin_serial_reg = { 1173static struct uart_driver bfin_serial_reg = {
1101 .owner = THIS_MODULE, 1174 .owner = THIS_MODULE,