diff options
author | Paul Mundt <lethal@linux-sh.org> | 2007-03-08 03:27:37 -0500 |
---|---|---|
committer | Paul Mundt <lethal@hera.kernel.org> | 2007-05-06 22:10:51 -0400 |
commit | fa5da2f7bdcf885efe65a37df13907c7d72296f6 (patch) | |
tree | 54104d5f660a1ec824505b28540eb2c5e4be390a /drivers/serial/sh-sci.c | |
parent | 15700770ef7c5d12e2f1659d2ddbeb3f658d9f37 (diff) |
sh: Bring kgdb back from the dead.
This code has suffered quite a bit of bitrot, do some basic
tidying to get it to a reasonably functional state again.
This gets the basic support and the console working again.
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/serial/sh-sci.c')
-rw-r--r-- | drivers/serial/sh-sci.c | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 46c40bbc4bc6..4b17f845f5cd 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #endif | 46 | #endif |
47 | 47 | ||
48 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) | 48 | #if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64) |
49 | #include <linux/ctype.h> | ||
49 | #include <asm/clock.h> | 50 | #include <asm/clock.h> |
50 | #include <asm/sh_bios.h> | 51 | #include <asm/sh_bios.h> |
51 | #include <asm/kgdb.h> | 52 | #include <asm/kgdb.h> |
@@ -163,7 +164,7 @@ static void put_string(struct sci_port *sci_port, const char *buffer, int count) | |||
163 | usegdb |= sh_bios_in_gdb_mode(); | 164 | usegdb |= sh_bios_in_gdb_mode(); |
164 | #endif | 165 | #endif |
165 | #ifdef CONFIG_SH_KGDB | 166 | #ifdef CONFIG_SH_KGDB |
166 | usegdb |= (kgdb_in_gdb_mode && (port == kgdb_sci_port)); | 167 | usegdb |= (kgdb_in_gdb_mode && (sci_port == kgdb_sci_port)); |
167 | #endif | 168 | #endif |
168 | 169 | ||
169 | if (usegdb) { | 170 | if (usegdb) { |
@@ -204,7 +205,7 @@ static int kgdb_sci_getchar(void) | |||
204 | int c; | 205 | int c; |
205 | 206 | ||
206 | /* Keep trying to read a character, this could be neater */ | 207 | /* Keep trying to read a character, this could be neater */ |
207 | while ((c = get_char(kgdb_sci_port)) < 0) | 208 | while ((c = get_char(&kgdb_sci_port->port)) < 0) |
208 | cpu_relax(); | 209 | cpu_relax(); |
209 | 210 | ||
210 | return c; | 211 | return c; |
@@ -212,7 +213,7 @@ static int kgdb_sci_getchar(void) | |||
212 | 213 | ||
213 | static inline void kgdb_sci_putchar(int c) | 214 | static inline void kgdb_sci_putchar(int c) |
214 | { | 215 | { |
215 | put_char(kgdb_sci_port, c); | 216 | put_char(&kgdb_sci_port->port, c); |
216 | } | 217 | } |
217 | #endif /* CONFIG_SH_KGDB */ | 218 | #endif /* CONFIG_SH_KGDB */ |
218 | 219 | ||
@@ -738,7 +739,7 @@ static irqreturn_t sci_br_interrupt(int irq, void *ptr) | |||
738 | 739 | ||
739 | #ifdef CONFIG_SH_KGDB | 740 | #ifdef CONFIG_SH_KGDB |
740 | /* Break into the debugger if a break is detected */ | 741 | /* Break into the debugger if a break is detected */ |
741 | BREAKPOINT(); | 742 | breakpoint(); |
742 | #endif | 743 | #endif |
743 | 744 | ||
744 | sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port)); | 745 | sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port)); |
@@ -971,7 +972,6 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
971 | { | 972 | { |
972 | struct sci_port *s = &sci_ports[port->line]; | 973 | struct sci_port *s = &sci_ports[port->line]; |
973 | unsigned int status, baud, smr_val; | 974 | unsigned int status, baud, smr_val; |
974 | unsigned long flags; | ||
975 | int t; | 975 | int t; |
976 | 976 | ||
977 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 977 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); |
@@ -989,12 +989,10 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
989 | #else | 989 | #else |
990 | t = SCBRR_VALUE(baud); | 990 | t = SCBRR_VALUE(baud); |
991 | #endif | 991 | #endif |
992 | } | ||
993 | break; | 992 | break; |
993 | } | ||
994 | } | 994 | } |
995 | 995 | ||
996 | spin_lock_irqsave(&port->lock, flags); | ||
997 | |||
998 | do { | 996 | do { |
999 | status = sci_in(port, SCxSR); | 997 | status = sci_in(port, SCxSR); |
1000 | } while (!(status & SCxSR_TEND(port))); | 998 | } while (!(status & SCxSR_TEND(port))); |
@@ -1038,8 +1036,6 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
1038 | 1036 | ||
1039 | if ((termios->c_cflag & CREAD) != 0) | 1037 | if ((termios->c_cflag & CREAD) != 0) |
1040 | sci_start_rx(port,0); | 1038 | sci_start_rx(port,0); |
1041 | |||
1042 | spin_unlock_irqrestore(&port->lock, flags); | ||
1043 | } | 1039 | } |
1044 | 1040 | ||
1045 | static const char *sci_type(struct uart_port *port) | 1041 | static const char *sci_type(struct uart_port *port) |
@@ -1220,8 +1216,6 @@ static int __init serial_console_setup(struct console *co, char *options) | |||
1220 | if (!port->membase || !port->mapbase) | 1216 | if (!port->membase || !port->mapbase) |
1221 | return -ENODEV; | 1217 | return -ENODEV; |
1222 | 1218 | ||
1223 | spin_lock_init(&port->lock); | ||
1224 | |||
1225 | port->type = serial_console_port->type; | 1219 | port->type = serial_console_port->type; |
1226 | 1220 | ||
1227 | if (port->flags & UPF_IOREMAP) | 1221 | if (port->flags & UPF_IOREMAP) |
@@ -1247,7 +1241,7 @@ static struct console serial_console = { | |||
1247 | .device = uart_console_device, | 1241 | .device = uart_console_device, |
1248 | .write = serial_console_write, | 1242 | .write = serial_console_write, |
1249 | .setup = serial_console_setup, | 1243 | .setup = serial_console_setup, |
1250 | .flags = CON_PRINTBUFFER, | 1244 | .flags = CON_PRINTBUFFER, |
1251 | .index = -1, | 1245 | .index = -1, |
1252 | .data = &sci_uart_driver, | 1246 | .data = &sci_uart_driver, |
1253 | }; | 1247 | }; |
@@ -1292,11 +1286,23 @@ int __init kgdb_console_setup(struct console *co, char *options) | |||
1292 | int parity = 'n'; | 1286 | int parity = 'n'; |
1293 | int flow = 'n'; | 1287 | int flow = 'n'; |
1294 | 1288 | ||
1295 | spin_lock_init(&port->lock); | ||
1296 | |||
1297 | if (co->index != kgdb_portnum) | 1289 | if (co->index != kgdb_portnum) |
1298 | co->index = kgdb_portnum; | 1290 | co->index = kgdb_portnum; |
1299 | 1291 | ||
1292 | kgdb_sci_port = &sci_ports[co->index]; | ||
1293 | port = &kgdb_sci_port->port; | ||
1294 | |||
1295 | /* | ||
1296 | * Also need to check port->type, we don't actually have any | ||
1297 | * UPIO_PORT ports, but uart_report_port() handily misreports | ||
1298 | * it anyways if we don't have a port available by the time this is | ||
1299 | * called. | ||
1300 | */ | ||
1301 | if (!port->type) | ||
1302 | return -ENODEV; | ||
1303 | if (!port->membase || !port->mapbase) | ||
1304 | return -ENODEV; | ||
1305 | |||
1300 | if (options) | 1306 | if (options) |
1301 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 1307 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
1302 | else | 1308 | else |
@@ -1311,11 +1317,12 @@ int __init kgdb_console_setup(struct console *co, char *options) | |||
1311 | 1317 | ||
1312 | #ifdef CONFIG_SH_KGDB_CONSOLE | 1318 | #ifdef CONFIG_SH_KGDB_CONSOLE |
1313 | static struct console kgdb_console = { | 1319 | static struct console kgdb_console = { |
1314 | .name = "ttySC", | 1320 | .name = "ttySC", |
1315 | .write = kgdb_console_write, | 1321 | .device = uart_console_device, |
1316 | .setup = kgdb_console_setup, | 1322 | .write = kgdb_console_write, |
1317 | .flags = CON_PRINTBUFFER | CON_ENABLED, | 1323 | .setup = kgdb_console_setup, |
1318 | .index = -1, | 1324 | .flags = CON_PRINTBUFFER, |
1325 | .index = -1, | ||
1319 | .data = &sci_uart_driver, | 1326 | .data = &sci_uart_driver, |
1320 | }; | 1327 | }; |
1321 | 1328 | ||
@@ -1386,6 +1393,12 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1386 | uart_add_one_port(&sci_uart_driver, &sciport->port); | 1393 | uart_add_one_port(&sci_uart_driver, &sciport->port); |
1387 | } | 1394 | } |
1388 | 1395 | ||
1396 | #if defined(CONFIG_SH_KGDB) && !defined(CONFIG_SH_KGDB_CONSOLE) | ||
1397 | kgdb_sci_port = &sci_ports[kgdb_portnum]; | ||
1398 | kgdb_getchar = kgdb_sci_getchar; | ||
1399 | kgdb_putchar = kgdb_sci_putchar; | ||
1400 | #endif | ||
1401 | |||
1389 | #ifdef CONFIG_CPU_FREQ | 1402 | #ifdef CONFIG_CPU_FREQ |
1390 | cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); | 1403 | cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER); |
1391 | dev_info(&dev->dev, "sci: CPU frequency notifier registered\n"); | 1404 | dev_info(&dev->dev, "sci: CPU frequency notifier registered\n"); |