aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/bfin_5xx.c
diff options
context:
space:
mode:
authorSonic Zhang <sonic.zhang@analog.com>2007-06-29 04:35:17 -0400
committerBryan Wu <bryan.wu@analog.com>2007-06-29 04:35:17 -0400
commit474f1a667d4bd40b6dcacc6870b70f4d2ba4e155 (patch)
tree42814169b151897ae679c543d0bc11aecde80b86 /drivers/serial/bfin_5xx.c
parent1c5d2265a82f8d3fa0471a60ca98072b3c53c299 (diff)
Blackfin arch: kgdb specific code
Signed-off-by: Sonic Zhang <sonic.zhang@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.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 22569bd5d821..f7926dc7fa78 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -41,6 +41,11 @@
41#include <linux/tty_flip.h> 41#include <linux/tty_flip.h>
42#include <linux/serial_core.h> 42#include <linux/serial_core.h>
43 43
44#ifdef CONFIG_KGDB_UART
45#include <linux/kgdb.h>
46#include <asm/irq_regs.h>
47#endif
48
44#include <asm/gpio.h> 49#include <asm/gpio.h>
45#include <asm/mach/bfin_serial_5xx.h> 50#include <asm/mach/bfin_serial_5xx.h>
46 51
@@ -119,6 +124,9 @@ static void bfin_serial_stop_rx(struct uart_port *port)
119 unsigned short ier; 124 unsigned short ier;
120 125
121 ier = UART_GET_IER(uart); 126 ier = UART_GET_IER(uart);
127#ifdef CONFIG_KGDB_UART
128 if (uart->port.line != CONFIG_KGDB_UART_PORT)
129#endif
122 ier &= ~ERBFI; 130 ier &= ~ERBFI;
123 UART_PUT_IER(uart, ier); 131 UART_PUT_IER(uart, ier);
124} 132}
@@ -130,6 +138,49 @@ static void bfin_serial_enable_ms(struct uart_port *port)
130{ 138{
131} 139}
132 140
141#ifdef CONFIG_KGDB_UART
142static int kgdb_entry_state;
143
144void kgdb_put_debug_char(int chr)
145{
146 struct bfin_serial_port *uart;
147
148 if (CONFIG_KGDB_UART_PORT<0 || CONFIG_KGDB_UART_PORT>=NR_PORTS)
149 uart = &bfin_serial_ports[0];
150 else
151 uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
152
153 while (!(UART_GET_LSR(uart) & THRE)) {
154 __builtin_bfin_ssync();
155 }
156 UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB));
157 __builtin_bfin_ssync();
158 UART_PUT_CHAR(uart, (unsigned char)chr);
159 __builtin_bfin_ssync();
160}
161
162int kgdb_get_debug_char(void)
163{
164 struct bfin_serial_port *uart;
165 unsigned char chr;
166
167 if (CONFIG_KGDB_UART_PORT<0 || CONFIG_KGDB_UART_PORT>=NR_PORTS)
168 uart = &bfin_serial_ports[0];
169 else
170 uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
171
172 while(!(UART_GET_LSR(uart) & DR)) {
173 __builtin_bfin_ssync();
174 }
175 UART_PUT_LCR(uart, UART_GET_LCR(uart)&(~DLAB));
176 __builtin_bfin_ssync();
177 chr = UART_GET_CHAR(uart);
178 __builtin_bfin_ssync();
179
180 return chr;
181}
182#endif
183
133#ifdef CONFIG_SERIAL_BFIN_PIO 184#ifdef CONFIG_SERIAL_BFIN_PIO
134static void local_put_char(struct bfin_serial_port *uart, char ch) 185static void local_put_char(struct bfin_serial_port *uart, char ch)
135{ 186{
@@ -152,6 +203,9 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
152{ 203{
153 struct tty_struct *tty = uart->port.info->tty; 204 struct tty_struct *tty = uart->port.info->tty;
154 unsigned int status, ch, flg; 205 unsigned int status, ch, flg;
206#ifdef CONFIG_KGDB_UART
207 struct pt_regs *regs = get_irq_regs();
208#endif
155#ifdef BF533_FAMILY 209#ifdef BF533_FAMILY
156 static int in_break = 0; 210 static int in_break = 0;
157#endif 211#endif
@@ -160,6 +214,27 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
160 ch = UART_GET_CHAR(uart); 214 ch = UART_GET_CHAR(uart);
161 uart->port.icount.rx++; 215 uart->port.icount.rx++;
162 216
217#ifdef CONFIG_KGDB_UART
218 if (uart->port.line == CONFIG_KGDB_UART_PORT) {
219 if (uart->port.cons->index == CONFIG_KGDB_UART_PORT && ch == 0x1) { /* Ctrl + A */
220 kgdb_breakkey_pressed(regs);
221 return;
222 } else if (kgdb_entry_state == 0 && ch == '$') {/* connection from KGDB */
223 kgdb_entry_state = 1;
224 } else if (kgdb_entry_state == 1 && ch == 'q') {
225 kgdb_entry_state = 0;
226 kgdb_breakkey_pressed(regs);
227 return;
228 } else if (ch == 0x3) {/* Ctrl + C */
229 kgdb_entry_state = 0;
230 kgdb_breakkey_pressed(regs);
231 return;
232 } else {
233 kgdb_entry_state = 0;
234 }
235 }
236#endif
237
163#ifdef BF533_FAMILY 238#ifdef BF533_FAMILY
164 /* The BF533 family of processors have a nice misbehavior where 239 /* The BF533 family of processors have a nice misbehavior where
165 * they continuously generate characters for a "single" break. 240 * they continuously generate characters for a "single" break.
@@ -571,7 +646,11 @@ static int bfin_serial_startup(struct uart_port *port)
571 uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; 646 uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES;
572 add_timer(&(uart->rx_dma_timer)); 647 add_timer(&(uart->rx_dma_timer));
573#else 648#else
649# ifdef CONFIG_KGDB_UART
650 if (uart->port.line != CONFIG_KGDB_UART_PORT && request_irq
651# else
574 if (request_irq 652 if (request_irq
653# endif
575 (uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED, 654 (uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED,
576 "BFIN_UART_RX", uart)) { 655 "BFIN_UART_RX", uart)) {
577 printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n"); 656 printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n");
@@ -601,6 +680,9 @@ static void bfin_serial_shutdown(struct uart_port *port)
601 free_dma(uart->rx_dma_channel); 680 free_dma(uart->rx_dma_channel);
602 del_timer(&(uart->rx_dma_timer)); 681 del_timer(&(uart->rx_dma_timer));
603#else 682#else
683#ifdef CONFIG_KGDB_UART
684 if (uart->port.line != CONFIG_KGDB_UART_PORT)
685#endif
604 free_irq(uart->port.irq, uart); 686 free_irq(uart->port.irq, uart);
605 free_irq(uart->port.irq+1, uart); 687 free_irq(uart->port.irq+1, uart);
606#endif 688#endif
@@ -931,6 +1013,10 @@ static int __init bfin_serial_rs_console_init(void)
931{ 1013{
932 bfin_serial_init_ports(); 1014 bfin_serial_init_ports();
933 register_console(&bfin_serial_console); 1015 register_console(&bfin_serial_console);
1016#ifdef CONFIG_KGDB_UART
1017 kgdb_entry_state = 0;
1018 init_kgdb_uart();
1019#endif
934 return 0; 1020 return 0;
935} 1021}
936console_initcall(bfin_serial_rs_console_init); 1022console_initcall(bfin_serial_rs_console_init);
@@ -1023,6 +1109,10 @@ static struct platform_driver bfin_serial_driver = {
1023static int __init bfin_serial_init(void) 1109static int __init bfin_serial_init(void)
1024{ 1110{
1025 int ret; 1111 int ret;
1112#ifdef CONFIG_KGDB_UART
1113 struct bfin_serial_port *uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
1114 struct termios t;
1115#endif
1026 1116
1027 pr_info("Serial: Blackfin serial driver\n"); 1117 pr_info("Serial: Blackfin serial driver\n");
1028 1118
@@ -1036,6 +1126,21 @@ static int __init bfin_serial_init(void)
1036 uart_unregister_driver(&bfin_serial_reg); 1126 uart_unregister_driver(&bfin_serial_reg);
1037 } 1127 }
1038 } 1128 }
1129#ifdef CONFIG_KGDB_UART
1130 if (uart->port.cons->index != CONFIG_KGDB_UART_PORT) {
1131 request_irq(uart->port.irq, bfin_serial_int,
1132 IRQF_DISABLED, "BFIN_UART_RX", uart);
1133 pr_info("Request irq for kgdb uart port\n");
1134 UART_PUT_IER(uart, UART_GET_IER(uart) | ERBFI);
1135 __builtin_bfin_ssync();
1136 t.c_cflag = CS8|B57600;
1137 t.c_iflag = 0;
1138 t.c_oflag = 0;
1139 t.c_lflag = ICANON;
1140 t.c_line = CONFIG_KGDB_UART_PORT;
1141 bfin_serial_set_termios(&uart->port, &t, &t);
1142 }
1143#endif
1039 return ret; 1144 return ret;
1040} 1145}
1041 1146