aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/bfin_5xx.c
diff options
context:
space:
mode:
authorSonic Zhang <sonic.zhang@analog.com>2009-01-02 08:40:14 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-02 13:19:34 -0500
commit52e15f0eae193a8e4ca31c1520179b8d65c79811 (patch)
treeb904fe05f51100d94477a6cb38ea621f4732bf8f /drivers/serial/bfin_5xx.c
parentb58602a4bac012b5f4fc12fe6b46ab237b610d5d (diff)
Blackfin Serial Driver: updates kgdb over Blackfin serial driver with kgdb framework
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com> Signed-off-by: Bryan Wu <cooloney@kernel.org> Signed-off-by: Alan Cox <alan@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/serial/bfin_5xx.c')
-rw-r--r--drivers/serial/bfin_5xx.c187
1 files changed, 89 insertions, 98 deletions
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 569f0e2476c6..d63fad7363b7 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -22,7 +22,8 @@
22#include <linux/tty_flip.h> 22#include <linux/tty_flip.h>
23#include <linux/serial_core.h> 23#include <linux/serial_core.h>
24 24
25#ifdef CONFIG_KGDB_UART 25#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
26 defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
26#include <linux/kgdb.h> 27#include <linux/kgdb.h>
27#include <asm/irq_regs.h> 28#include <asm/irq_regs.h>
28#endif 29#endif
@@ -45,6 +46,16 @@
45static struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS]; 46static struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS];
46static int nr_active_ports = ARRAY_SIZE(bfin_serial_resource); 47static int nr_active_ports = ARRAY_SIZE(bfin_serial_resource);
47 48
49#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
50 defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
51
52# ifndef CONFIG_SERIAL_BFIN_PIO
53# error KGDB only support UART in PIO mode.
54# endif
55
56static int kgdboc_port_line;
57static int kgdboc_break_enabled;
58#endif
48/* 59/*
49 * Setup for console. Argument comes from the menuconfig 60 * Setup for console. Argument comes from the menuconfig
50 */ 61 */
@@ -110,9 +121,7 @@ static void bfin_serial_start_tx(struct uart_port *port)
110static void bfin_serial_stop_rx(struct uart_port *port) 121static void bfin_serial_stop_rx(struct uart_port *port)
111{ 122{
112 struct bfin_serial_port *uart = (struct bfin_serial_port *)port; 123 struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
113#ifdef CONFIG_KGDB_UART 124
114 if (uart->port.line != CONFIG_KGDB_UART_PORT)
115#endif
116 UART_CLEAR_IER(uart, ERBFI); 125 UART_CLEAR_IER(uart, ERBFI);
117} 126}
118 127
@@ -123,49 +132,6 @@ static void bfin_serial_enable_ms(struct uart_port *port)
123{ 132{
124} 133}
125 134
126#ifdef CONFIG_KGDB_UART
127static int kgdb_entry_state;
128
129void kgdb_put_debug_char(int chr)
130{
131 struct bfin_serial_port *uart;
132
133 if (CONFIG_KGDB_UART_PORT < 0
134 || CONFIG_KGDB_UART_PORT >= BFIN_UART_NR_PORTS)
135 uart = &bfin_serial_ports[0];
136 else
137 uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
138
139 while (!(UART_GET_LSR(uart) & THRE)) {
140 SSYNC();
141 }
142
143 UART_CLEAR_DLAB(uart);
144 UART_PUT_CHAR(uart, (unsigned char)chr);
145 SSYNC();
146}
147
148int kgdb_get_debug_char(void)
149{
150 struct bfin_serial_port *uart;
151 unsigned char chr;
152
153 if (CONFIG_KGDB_UART_PORT < 0
154 || CONFIG_KGDB_UART_PORT >= BFIN_UART_NR_PORTS)
155 uart = &bfin_serial_ports[0];
156 else
157 uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
158
159 while(!(UART_GET_LSR(uart) & DR)) {
160 SSYNC();
161 }
162 UART_CLEAR_DLAB(uart);
163 chr = UART_GET_CHAR(uart);
164 SSYNC();
165
166 return chr;
167}
168#endif
169 135
170#if ANOMALY_05000363 && defined(CONFIG_SERIAL_BFIN_PIO) 136#if ANOMALY_05000363 && defined(CONFIG_SERIAL_BFIN_PIO)
171# define UART_GET_ANOMALY_THRESHOLD(uart) ((uart)->anomaly_threshold) 137# define UART_GET_ANOMALY_THRESHOLD(uart) ((uart)->anomaly_threshold)
@@ -178,7 +144,7 @@ int kgdb_get_debug_char(void)
178#ifdef CONFIG_SERIAL_BFIN_PIO 144#ifdef CONFIG_SERIAL_BFIN_PIO
179static void bfin_serial_rx_chars(struct bfin_serial_port *uart) 145static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
180{ 146{
181 struct tty_struct *tty = uart->port.info->port.tty; 147 struct tty_struct *tty = NULL;
182 unsigned int status, ch, flg; 148 unsigned int status, ch, flg;
183 static struct timeval anomaly_start = { .tv_sec = 0 }; 149 static struct timeval anomaly_start = { .tv_sec = 0 };
184 150
@@ -188,27 +154,18 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
188 ch = UART_GET_CHAR(uart); 154 ch = UART_GET_CHAR(uart);
189 uart->port.icount.rx++; 155 uart->port.icount.rx++;
190 156
191#ifdef CONFIG_KGDB_UART 157#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
192 if (uart->port.line == CONFIG_KGDB_UART_PORT) { 158 defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
193 struct pt_regs *regs = get_irq_regs(); 159 if (kgdb_connected && kgdboc_port_line == uart->port.line)
194 if (uart->port.cons->index == CONFIG_KGDB_UART_PORT && ch == 0x1) { /* Ctrl + A */ 160 if (ch == 0x3) {/* Ctrl + C */
195 kgdb_breakkey_pressed(regs); 161 kgdb_breakpoint();
196 return;
197 } else if (kgdb_entry_state == 0 && ch == '$') {/* connection from KGDB */
198 kgdb_entry_state = 1;
199 } else if (kgdb_entry_state == 1 && ch == 'q') {
200 kgdb_entry_state = 0;
201 kgdb_breakkey_pressed(regs);
202 return; 162 return;
203 } else if (ch == 0x3) {/* Ctrl + C */
204 kgdb_entry_state = 0;
205 kgdb_breakkey_pressed(regs);
206 return;
207 } else {
208 kgdb_entry_state = 0;
209 } 163 }
210 } 164
165 if (!uart->port.info || !uart->port.info->tty)
166 return;
211#endif 167#endif
168 tty = uart->port.info->tty;
212 169
213 if (ANOMALY_05000363) { 170 if (ANOMALY_05000363) {
214 /* The BF533 (and BF561) family of processors have a nice anomaly 171 /* The BF533 (and BF561) family of processors have a nice anomaly
@@ -630,16 +587,16 @@ static int bfin_serial_startup(struct uart_port *port)
630 uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES; 587 uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES;
631 add_timer(&(uart->rx_dma_timer)); 588 add_timer(&(uart->rx_dma_timer));
632#else 589#else
590#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
591 defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
592 if (kgdboc_port_line == uart->port.line && kgdboc_break_enabled)
593 kgdboc_break_enabled = 0;
594 else {
595# endif
633 if (request_irq(uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED, 596 if (request_irq(uart->port.irq, bfin_serial_rx_int, IRQF_DISABLED,
634 "BFIN_UART_RX", uart)) { 597 "BFIN_UART_RX", uart)) {
635# ifdef CONFIG_KGDB_UART
636 if (uart->port.line != CONFIG_KGDB_UART_PORT) {
637# endif
638 printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n"); 598 printk(KERN_NOTICE "Unable to attach BlackFin UART RX interrupt\n");
639 return -EBUSY; 599 return -EBUSY;
640# ifdef CONFIG_KGDB_UART
641 }
642# endif
643 } 600 }
644 601
645 if (request_irq 602 if (request_irq
@@ -685,6 +642,10 @@ static int bfin_serial_startup(struct uart_port *port)
685 } 642 }
686 } 643 }
687# endif 644# endif
645#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
646 defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
647 }
648# endif
688#endif 649#endif
689 UART_SET_IER(uart, ERBFI); 650 UART_SET_IER(uart, ERBFI);
690 return 0; 651 return 0;
@@ -716,9 +677,6 @@ static void bfin_serial_shutdown(struct uart_port *port)
716 break; 677 break;
717 }; 678 };
718#endif 679#endif
719#ifdef CONFIG_KGDB_UART
720 if (uart->port.line != CONFIG_KGDB_UART_PORT)
721#endif
722 free_irq(uart->port.irq, uart); 680 free_irq(uart->port.irq, uart);
723 free_irq(uart->port.irq+1, uart); 681 free_irq(uart->port.irq+1, uart);
724#endif 682#endif
@@ -887,6 +845,51 @@ static void bfin_serial_set_ldisc(struct uart_port *port)
887 } 845 }
888} 846}
889 847
848#ifdef CONFIG_CONSOLE_POLL
849static void bfin_serial_poll_put_char(struct uart_port *port, unsigned char chr)
850{
851 struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
852
853 while (!(UART_GET_LSR(uart) & THRE))
854 cpu_relax();
855
856 UART_CLEAR_DLAB(uart);
857 UART_PUT_CHAR(uart, (unsigned char)chr);
858}
859
860static int bfin_serial_poll_get_char(struct uart_port *port)
861{
862 struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
863 unsigned char chr;
864
865 while (!(UART_GET_LSR(uart) & DR))
866 cpu_relax();
867
868 UART_CLEAR_DLAB(uart);
869 chr = UART_GET_CHAR(uart);
870
871 return chr;
872}
873#endif
874
875#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
876 defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
877static void bfin_kgdboc_port_shutdown(struct uart_port *port)
878{
879 if (kgdboc_break_enabled) {
880 kgdboc_break_enabled = 0;
881 bfin_serial_shutdown(port);
882 }
883}
884
885static int bfin_kgdboc_port_startup(struct uart_port *port)
886{
887 kgdboc_port_line = port->line;
888 kgdboc_break_enabled = !bfin_serial_startup(port);
889 return 0;
890}
891#endif
892
890static struct uart_ops bfin_serial_pops = { 893static struct uart_ops bfin_serial_pops = {
891 .tx_empty = bfin_serial_tx_empty, 894 .tx_empty = bfin_serial_tx_empty,
892 .set_mctrl = bfin_serial_set_mctrl, 895 .set_mctrl = bfin_serial_set_mctrl,
@@ -905,6 +908,15 @@ static struct uart_ops bfin_serial_pops = {
905 .request_port = bfin_serial_request_port, 908 .request_port = bfin_serial_request_port,
906 .config_port = bfin_serial_config_port, 909 .config_port = bfin_serial_config_port,
907 .verify_port = bfin_serial_verify_port, 910 .verify_port = bfin_serial_verify_port,
911#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
912 defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
913 .kgdboc_port_startup = bfin_kgdboc_port_startup,
914 .kgdboc_port_shutdown = bfin_kgdboc_port_shutdown,
915#endif
916#ifdef CONFIG_CONSOLE_POLL
917 .poll_put_char = bfin_serial_poll_put_char,
918 .poll_get_char = bfin_serial_poll_get_char,
919#endif
908}; 920};
909 921
910static void __init bfin_serial_init_ports(void) 922static void __init bfin_serial_init_ports(void)
@@ -1076,10 +1088,7 @@ static int __init bfin_serial_rs_console_init(void)
1076{ 1088{
1077 bfin_serial_init_ports(); 1089 bfin_serial_init_ports();
1078 register_console(&bfin_serial_console); 1090 register_console(&bfin_serial_console);
1079#ifdef CONFIG_KGDB_UART 1091
1080 kgdb_entry_state = 0;
1081 init_kgdb_uart();
1082#endif
1083 return 0; 1092 return 0;
1084} 1093}
1085console_initcall(bfin_serial_rs_console_init); 1094console_initcall(bfin_serial_rs_console_init);
@@ -1235,10 +1244,6 @@ static struct platform_driver bfin_serial_driver = {
1235static int __init bfin_serial_init(void) 1244static int __init bfin_serial_init(void)
1236{ 1245{
1237 int ret; 1246 int ret;
1238#ifdef CONFIG_KGDB_UART
1239 struct bfin_serial_port *uart = &bfin_serial_ports[CONFIG_KGDB_UART_PORT];
1240 struct ktermios t;
1241#endif
1242 1247
1243 pr_info("Serial: Blackfin serial driver\n"); 1248 pr_info("Serial: Blackfin serial driver\n");
1244 1249
@@ -1252,21 +1257,6 @@ static int __init bfin_serial_init(void)
1252 uart_unregister_driver(&bfin_serial_reg); 1257 uart_unregister_driver(&bfin_serial_reg);
1253 } 1258 }
1254 } 1259 }
1255#ifdef CONFIG_KGDB_UART
1256 if (uart->port.cons->index != CONFIG_KGDB_UART_PORT) {
1257 request_irq(uart->port.irq, bfin_serial_rx_int,
1258 IRQF_DISABLED, "BFIN_UART_RX", uart);
1259 pr_info("Request irq for kgdb uart port\n");
1260 UART_SET_IER(uart, ERBFI);
1261 SSYNC();
1262 t.c_cflag = CS8|B57600;
1263 t.c_iflag = 0;
1264 t.c_oflag = 0;
1265 t.c_lflag = ICANON;
1266 t.c_line = CONFIG_KGDB_UART_PORT;
1267 bfin_serial_set_termios(&uart->port, &t, &t);
1268 }
1269#endif
1270 return ret; 1260 return ret;
1271} 1261}
1272 1262
@@ -1276,6 +1266,7 @@ static void __exit bfin_serial_exit(void)
1276 uart_unregister_driver(&bfin_serial_reg); 1266 uart_unregister_driver(&bfin_serial_reg);
1277} 1267}
1278 1268
1269
1279module_init(bfin_serial_init); 1270module_init(bfin_serial_init);
1280module_exit(bfin_serial_exit); 1271module_exit(bfin_serial_exit);
1281 1272